public virtual async Task <T> GetByIdAsync(Id id, ICommandOptions options = null)
        {
            if (String.IsNullOrEmpty(id.Value))
            {
                return(null);
            }

            T hit = null;

            if (IsCacheEnabled && options.ShouldReadCache())
            {
                hit = await Cache.GetAsync <T>(id, default).AnyContext();
            }

            bool isTraceLogLevelEnabled = _logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Trace);

            if (hit != null)
            {
                if (isTraceLogLevelEnabled)
                {
                    _logger.LogTrace("Cache hit: type={ElasticType} key={Id}", ElasticType.Name, id);
                }
                return(hit);
            }

            if (!HasParent || id.Routing != null)
            {
                var request = new GetRequest(GetIndexById(id), ElasticType.Name, id.Value);
                if (id.Routing != null)
                {
                    request.Routing = id.Routing;
                }
                var response = await _client.GetAsync <T>(request).AnyContext();

                if (isTraceLogLevelEnabled)
                {
                    _logger.LogTrace(response.GetRequest());
                }

                hit = response.Found ? response.ToFindHit().Document : null;
            }
            else
            {
                // we don't have the parent id so we have to do a query
                // TODO: Ensure this is find one query is not cached.
                var findResult = await FindOneAsync(NewQuery().Id(id)).AnyContext();

                if (findResult != null)
                {
                    hit = findResult.Document;
                }
            }

            if (hit != null && IsCacheEnabled && options.ShouldUseCache())
            {
                await Cache.SetAsync(id, hit, options.GetExpiresIn()).AnyContext();
            }

            return(hit);
        }
예제 #2
0
        protected override async Task AddDocumentsToCacheAsync(ICollection <FindHit <Employee> > findHits, ICommandOptions options)
        {
            await base.AddDocumentsToCacheAsync(findHits, options);

            var cacheEntries = new Dictionary <string, FindHit <Employee> >();

            foreach (var hit in findHits.Where(d => !String.IsNullOrEmpty(d.Document.EmailAddress)))
            {
                cacheEntries.Add($"email:{hit.Document.EmailAddress.ToLowerInvariant()}", hit);
            }

            await AddDocumentsToCacheWithKeyAsync(cacheEntries, options.GetExpiresIn());
        }
        protected override async Task AddToCacheAsync(ICollection <Stack> documents, ICommandOptions options)
        {
            if (!IsCacheEnabled || Cache == null || !options.ShouldUseCache())
            {
                return;
            }

            await base.AddToCacheAsync(documents, options).AnyContext();

            foreach (var stack in documents)
            {
                await Cache.SetAsync(GetStackSignatureCacheKey(stack), stack, options.GetExpiresIn()).AnyContext();
            }
        }
예제 #4
0
        protected override async Task AddDocumentsToCacheAsync(ICollection <FindHit <User> > findHits, ICommandOptions options)
        {
            await base.AddDocumentsToCacheAsync(findHits, options).AnyContext();

            var cacheEntries = new Dictionary <string, FindHit <User> >();

            foreach (var hit in findHits.Where(d => !String.IsNullOrEmpty(d.Document?.EmailAddress)))
            {
                cacheEntries.Add(EmailCacheKey(hit.Document.EmailAddress), hit);
            }

            if (cacheEntries.Count > 0)
            {
                await AddDocumentsToCacheWithKeyAsync(cacheEntries, options.GetExpiresIn()).AnyContext();
            }
        }
예제 #5
0
    protected override async Task AddDocumentsToCacheAsync(ICollection <FindHit <Stack> > findHits, ICommandOptions options, bool isDirtyRead)
    {
        await base.AddDocumentsToCacheAsync(findHits, options, isDirtyRead).AnyContext();

        var cacheEntries = new Dictionary <string, FindHit <Stack> >();

        foreach (var hit in findHits)
        {
            cacheEntries.Add(GetStackSignatureCacheKey(hit.Document), hit);
        }

        if (cacheEntries.Count > 0)
        {
            await AddDocumentsToCacheWithKeyAsync(cacheEntries, options.GetExpiresIn());
        }
    }
        protected async Task SetCachedQueryResultAsync <TResult>(ICommandOptions options, TResult result, string cachePrefix = null, string cacheSuffix = null)
        {
            if (!IsCacheEnabled || result == null || options == null || !options.ShouldUseCache() || !options.HasCacheKey())
            {
                return;
            }

            string cacheKey = cachePrefix != null ? cachePrefix + ":" + options.GetCacheKey() : options.GetCacheKey();

            if (!String.IsNullOrEmpty(cacheSuffix))
            {
                cacheKey += ":" + cacheSuffix;
            }

            await Cache.SetAsync(cacheKey, result, options.GetExpiresIn()).AnyContext();

            _logger.Trace(() => $"Set cache: type={ElasticType.Name} key={cacheKey}");
        }
        public async Task <IReadOnlyCollection <T> > GetByIdsAsync(Ids ids, ICommandOptions options = null)
        {
            var idList = ids?.Distinct().Where(i => !String.IsNullOrEmpty(i)).ToList();

            if (idList == null || idList.Count == 0)
            {
                return(EmptyList);
            }

            if (!HasIdentity)
            {
                throw new NotSupportedException("Model type must implement IIdentity.");
            }

            var hits = new List <T>();

            if (IsCacheEnabled && options.ShouldReadCache())
            {
                var cacheHits = await Cache.GetAllAsync <T>(idList.Select(id => id.Value)).AnyContext();

                hits.AddRange(cacheHits.Where(kvp => kvp.Value.HasValue).Select(kvp => kvp.Value.Value));
            }

            var itemsToFind = idList.Except(hits.OfType <IIdentity>().Select(i => (Id)i.Id)).ToList();

            if (itemsToFind.Count == 0)
            {
                return(hits.AsReadOnly());
            }

            var multiGet = new MultiGetDescriptor();

            foreach (var id in itemsToFind.Where(i => i.Routing != null || !HasParent))
            {
                multiGet.Get <T>(f => {
                    f.Id(id.Value).Index(GetIndexById(id)).Type(ElasticType.Name);
                    if (id.Routing != null)
                    {
                        f.Routing(id.Routing);
                    }

                    return(f);
                });
            }

            var multiGetResults = await _client.MultiGetAsync(multiGet).AnyContext();

            _logger.Trace(() => multiGetResults.GetRequest());

            foreach (var doc in multiGetResults.Documents)
            {
                if (!doc.Found)
                {
                    continue;
                }

                hits.Add(((IMultiGetHit <T>)doc).ToFindHit().Document);
                itemsToFind.Remove(doc.Id);
            }

            // fallback to doing a find
            if (itemsToFind.Count > 0 && (HasParent || HasMultipleIndexes))
            {
                var response = await FindAsync(q => q.Id(itemsToFind.Select(id => id.Value)), o => o.PageLimit(1000)).AnyContext();

                do
                {
                    if (response.Hits.Count > 0)
                    {
                        hits.AddRange(response.Hits.Where(h => h.Document != null).Select(h => h.Document));
                    }
                } while (await response.NextPageAsync().AnyContext());
            }

            if (IsCacheEnabled && options.ShouldUseCache())
            {
                foreach (var item in hits.OfType <IIdentity>())
                {
                    await Cache.SetAsync(item.Id, item, options.GetExpiresIn()).AnyContext();
                }
            }

            return(hits.AsReadOnly());
        }