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

            // documents that use soft deletes or have parents without a routing id need to use search for exists
            if (!SupportsSoftDeletes && (!HasParent || id.Routing != null))
            {
                var response = await _client.DocumentExistsAsync(new DocumentPath <T>(id.Value), d => {
                    d.Index(ElasticIndex.GetIndex(id));
                    if (id.Routing != null)
                    {
                        d.Routing(id.Routing);
                    }

                    return(d);
                }).AnyContext();

                _logger.LogRequest(response, options.GetQueryLogLevel());

                return(response.Exists);
            }

            return(await ExistsAsync(q => q.Id(id), o => options.As <T>()).AnyContext());
        }
コード例 #2
0
        public async Task <bool> IncrementEventCounterAsync(string organizationId, string projectId, string stackId, DateTime minOccurrenceDateUtc, DateTime maxOccurrenceDateUtc, int count, bool sendNotifications = true)
        {
            // If total occurrences are zero (stack data was reset), then set first occurrence date
            // Only update the LastOccurrence if the new date is greater then the existing date.
            const string script = @"
Instant parseDate(def dt) {
  if (dt != null) {
    try {
      return Instant.parse(dt);
    } catch(DateTimeParseException e) {}
  }
  return Instant.MIN;
}

if (ctx._source.total_occurrences == 0 || parseDate(ctx._source.first_occurrence).isAfter(parseDate(params.minOccurrenceDateUtc))) {
  ctx._source.first_occurrence = params.minOccurrenceDateUtc;
}
if (parseDate(ctx._source.last_occurrence).isBefore(parseDate(params.maxOccurrenceDateUtc))) {
  ctx._source.last_occurrence = params.maxOccurrenceDateUtc;
}
if (parseDate(ctx._source.updated_utc).isBefore(parseDate(params.updatedUtc))) {
  ctx._source.updated_utc = params.updatedUtc;
}
ctx._source.total_occurrences += params.count;";

            var request = new UpdateRequest <Stack, Stack>(ElasticIndex.GetIndex(stackId), stackId)
            {
                Script = new InlineScript(script.TrimScript())
                {
                    Params = new Dictionary <string, object>(3)
                    {
                        { "minOccurrenceDateUtc", minOccurrenceDateUtc },
                        { "maxOccurrenceDateUtc", maxOccurrenceDateUtc },
                        { "count", count },
                        { "updatedUtc", SystemClock.UtcNow }
                    }
                }
            };

            var result = await _client.UpdateAsync(request).AnyContext();

            if (!result.IsValid)
            {
                _logger.LogError(result.OriginalException, "Error occurred incrementing total event occurrences on stack {stack}. Error: {Message}", stackId, result.ServerError?.Error);
                return(result.ServerError?.Status == 404);
            }

            if (IsCacheEnabled)
            {
                await Cache.RemoveAsync(stackId).AnyContext();
            }

            if (sendNotifications)
            {
                await PublishMessageAsync(CreateEntityChanged(ChangeType.Saved, organizationId, projectId, null, stackId), TimeSpan.FromSeconds(1.5)).AnyContext();
            }

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

            options = ConfigureOptions(options.As <T>());
            if (IsCacheEnabled && options.HasCacheKey())
            {
                throw new ArgumentException("Cache key can't be set when calling GetById");
            }

            if (IsCacheEnabled && options.ShouldReadCache())
            {
                var value = await GetCachedFindHit(id).AnyContext();

                if (value?.Document != null)
                {
                    _logger.LogTrace("Cache hit: type={EntityType} key={Id}", EntityTypeName, id);

                    return(ShouldReturnDocument(value.Document, options) ? value.Document : null);
                }
            }

            FindHit <T> findHit;

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

                _logger.LogRequest(response, options.GetQueryLogLevel());

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

            if (IsCacheEnabled && options.ShouldUseCache())
            {
                await AddDocumentsToCacheAsync(findHit ?? new FindHit <T>(id, null, 0), options).AnyContext();
            }

            return(ShouldReturnDocument(findHit?.Document, options) ? findHit?.Document : null);
        }
        public virtual 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.");
            }

            options = ConfigureOptions(options.As <T>());
            if (IsCacheEnabled && options.HasCacheKey())
            {
                throw new ArgumentException("Cache key can't be set when calling GetByIds");
            }

            var hits = new List <FindHit <T> >();

            if (IsCacheEnabled && options.ShouldReadCache())
            {
                hits.AddRange(await GetCachedFindHit(idList).AnyContext());
            }

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

            if (itemsToFind.Count == 0)
            {
                return(hits.Where(h => h.Document != null && ShouldReturnDocument(h.Document, options)).Select(h => h.Document).ToList().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(ElasticIndex.GetIndex(id));
                    if (id.Routing != null)
                    {
                        f.Routing(id.Routing);
                    }

                    return(f);
                });
            }

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

            _logger.LogRequest(multiGetResults, options.GetQueryLogLevel());

            foreach (var doc in multiGetResults.Hits)
            {
                hits.Add(((IMultiGetHit <T>)doc).ToFindHit());
                itemsToFind.Remove(new Id(doc.Id, doc.Routing));
            }

            // fallback to doing a find
            if (itemsToFind.Count > 0 && (HasParent || ElasticIndex.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));
                    }
                } while (await response.NextPageAsync().AnyContext());
            }

            if (IsCacheEnabled && options.ShouldUseCache())
            {
                await AddDocumentsToCacheAsync(hits, options).AnyContext();
            }

            return(hits.Where(h => h.Document != null && ShouldReturnDocument(h.Document, options)).Select(h => h.Document).ToList().AsReadOnly());
        }