protected async Task <long> CountAsync(ElasticSearchOptions <T> options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (EnableCache && options.UseCache)
            {
                var cachedValue = await Cache.GetAsync <long>(GetScopedCacheKey("count-" + options.CacheKey)).AnyContext();

                if (cachedValue.HasValue)
                {
                    return(cachedValue.Value);
                }
            }

            var countDescriptor = new CountDescriptor <T>().Query(f => f.Filtered(s => s.Filter(f2 => options.GetElasticSearchFilter(_supportsSoftDeletes))));

            countDescriptor.Indices(options.Indices.Any()
                ? options.Indices.ToArray()
                : GetIndices());

            countDescriptor.IgnoreUnavailable();
            countDescriptor.Type(typeof(T));
#if DEBUG
            _elasticClient.EnableTrace();
            var sw = Stopwatch.StartNew();
#endif
            var results = await _elasticClient.CountAsync <T>(countDescriptor).AnyContext();

#if DEBUG
            sw.Stop();
            _elasticClient.DisableTrace();
            Logger.Trace().Message($"CountAsync: {sw.ElapsedMilliseconds}ms, Serialization Took {results.ConnectionStatus.Metrics.SerializationTime}ms, Deserialization Took {results.ConnectionStatus.Metrics.DeserializationTime}ms").Write();
#endif

            if (!results.IsValid)
            {
                throw new ApplicationException($"ElasticSearch error code \"{results.ConnectionStatus.HttpStatusCode}\".", results.ConnectionStatus.OriginalException);
            }

            if (EnableCache && options.UseCache)
            {
                await Cache.SetAsync(GetScopedCacheKey("count-" + options.CacheKey), results.Count, options.GetCacheExpirationDate()).AnyContext();
            }

            return(results.Count);
        }
        protected long Count(ElasticSearchOptions <T> options)
        {
            if (options == null)
            {
                throw new ArgumentNullException("options");
            }

            long?result;

            if (EnableCache && options.UseCache)
            {
                result = Cache.Get <long?>(GetScopedCacheKey("count-" + options.CacheKey));
                if (result.HasValue)
                {
                    return(result.Value);
                }
            }

            var countDescriptor = new CountDescriptor <T>().Query(f => f.Filtered(s => s.Filter(f2 => options.GetElasticSearchFilter())));

            countDescriptor.Indices(options.Indices);
            countDescriptor.IgnoreUnavailable();

            countDescriptor.Type(typeof(T));

            _elasticClient.EnableTrace();
            var results = _elasticClient.Count <T>(countDescriptor);

            _elasticClient.DisableTrace();

            if (!results.IsValid)
            {
                throw new ApplicationException(String.Format("ElasticSearch error code \"{0}\".", results.ConnectionStatus.HttpStatusCode), results.ConnectionStatus.OriginalException);
            }

            result = results.Count;

            if (EnableCache && options.UseCache)
            {
                Cache.Set(GetScopedCacheKey("count-" + options.CacheKey), result, options.GetCacheExpirationDate());
            }

            return(result.Value);
        }
        protected async Task <long> CountAsync(object query)
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }

            var result = IsCacheEnabled ? await GetCachedQueryResultAsync <long?>(query, "count").AnyContext() : null;

            if (result != null)
            {
                return(result.Value);
            }

            var countDescriptor = new CountDescriptor <T>().Query(Context.QueryBuilder.BuildQuery <T>(query));
            var indices         = GetIndexesByQuery(query);

            if (indices?.Length > 0)
            {
                countDescriptor.Indices(indices);
            }
            countDescriptor.IgnoreUnavailable();

            var results = await Context.ElasticClient.CountAsync <T>(countDescriptor).AnyContext();

            if (!results.IsValid)
            {
                throw new ApplicationException($"ElasticSearch error code \"{results.ConnectionStatus.HttpStatusCode}\".", results.ConnectionStatus.OriginalException);
            }

            if (IsCacheEnabled)
            {
                await SetCachedQueryResultAsync(query, results.Count, "count").AnyContext();
            }

            return(results.Count);
        }