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); }
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(); } }
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(); } }
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()); }