Exemple #1
0
        private void HandleFacets(
            List <ReaderFacetInfo> returnedReaders,
            KeyValuePair <string, FacetedQueryParser.FacetResult> result,
            Dictionary <string, Dictionary <string, FacetValues> > facetsByName,
            bool legacy, CancellationToken token)
        {
            var needToApplyAggregation = result.Value.Aggregations.Count > 0;

            foreach (var readerFacetInfo in returnedReaders)
            {
                var termsForField = IndexedTerms.GetTermsAndDocumentsFor(readerFacetInfo.Reader, readerFacetInfo.DocBase, result.Value.AggregateBy, _indexName, _state);

                if (facetsByName.TryGetValue(result.Key, out var facetValues) == false)
                {
                    facetsByName[result.Key] = facetValues = new Dictionary <string, FacetValues>();
                }

                foreach (var kvp in termsForField)
                {
                    token.ThrowIfCancellationRequested();

                    var intersectedDocuments = GetIntersectedDocuments(new ArraySegment <int>(kvp.Value), readerFacetInfo.Results, needToApplyAggregation);
                    var intersectCount       = intersectedDocuments.Count;
                    if (intersectCount == 0)
                    {
                        continue;
                    }

                    if (facetValues.TryGetValue(kvp.Key, out var collectionOfFacetValues) == false)
                    {
                        var range = FacetedQueryHelper.GetRangeName(result.Value.AggregateBy, kvp.Key);
                        collectionOfFacetValues = new FacetValues(legacy);
                        if (needToApplyAggregation == false)
                        {
                            collectionOfFacetValues.AddDefault(range);
                        }
                        else
                        {
                            foreach (var aggregation in result.Value.Aggregations)
                            {
                                collectionOfFacetValues.Add(aggregation.Key, range);
                            }
                        }

                        facetValues.Add(kvp.Key, collectionOfFacetValues);
                    }

                    collectionOfFacetValues.IncrementCount(intersectCount);

                    if (needToApplyAggregation)
                    {
                        var docsInQuery = new ArraySegment <int>(intersectedDocuments.Documents, 0, intersectedDocuments.Count);
                        ApplyAggregation(result.Value.Aggregations, collectionOfFacetValues, docsInQuery, readerFacetInfo.Reader, readerFacetInfo.DocBase, _state);
                    }
                }
            }
        }
Exemple #2
0
        private void HandleFacets(List <ReaderFacetInfo> returnedReaders, KeyValuePair <string, FacetedQueryParser.FacetResult> result, Dictionary <string, Dictionary <string, FacetValue> > facetsByName)
        {
            foreach (var readerFacetInfo in returnedReaders)
            {
                var termsForField = IndexedTerms.GetTermsAndDocumentsFor(readerFacetInfo.Reader, readerFacetInfo.DocBase, result.Value.AggregateBy, _indexName, _state);

                if (facetsByName.TryGetValue(result.Key, out Dictionary <string, FacetValue> facetValues) == false)
                {
                    facetsByName[result.Key] = facetValues = new Dictionary <string, FacetValue>();
                }

                foreach (var kvp in termsForField)
                {
                    var needToApplyAggregation = result.Value.Aggregations.Count > 0;
                    var intersectedDocuments   = GetIntersectedDocuments(new ArraySegment <int>(kvp.Value), readerFacetInfo.Results, needToApplyAggregation);
                    var intersectCount         = intersectedDocuments.Count;
                    if (intersectCount == 0)
                    {
                        continue;
                    }

                    if (facetValues.TryGetValue(kvp.Key, out FacetValue facetValue) == false)
                    {
                        facetValue = new FacetValue
                        {
                            Range = FacetedQueryHelper.GetRangeName(result.Value.AggregateBy, kvp.Key)
                        };
                        facetValues.Add(kvp.Key, facetValue);
                    }

                    facetValue.Count += intersectCount;

                    if (needToApplyAggregation)
                    {
                        var docsInQuery = new ArraySegment <int>(intersectedDocuments.Documents, 0, intersectedDocuments.Count);
                        ApplyAggregation(result.Value.Aggregations, facetValue, docsInQuery, readerFacetInfo.Reader, readerFacetInfo.DocBase, _state);
                    }
                }
            }
        }
Exemple #3
0
        public Dictionary <string, FacetResult> FacetedQuery(FacetQueryServerSide query, JsonOperationContext context, Func <string, SpatialField> getSpatialField, CancellationToken token)
        {
            var results = FacetedQueryParser.Parse(query.Facets, out Dictionary <string, Facet> defaultFacets, out Dictionary <string, List <FacetedQueryParser.ParsedRange> > rangeFacets);

            var facetsByName = new Dictionary <string, Dictionary <string, FacetValue> >();

            uint fieldsHash = 0;

            if (query.Metadata.IsDistinct)
            {
                fieldsHash = CalculateQueryFieldsHash(query);
            }

            var baseQuery       = GetLuceneQuery(context, query.Metadata, query.QueryParameters, _analyzer, getSpatialField);
            var returnedReaders = GetQueryMatchingDocuments(_searcher, baseQuery, _state);

            foreach (var facet in defaultFacets.Values)
            {
                if (facet.Mode != FacetMode.Default)
                {
                    continue;
                }

                Dictionary <string, HashSet <IndexSearcherHolder.StringCollectionValue> > distinctItems = null;
                HashSet <IndexSearcherHolder.StringCollectionValue> alreadySeen = null;
                if (query.Metadata.IsDistinct)
                {
                    distinctItems = new Dictionary <string, HashSet <IndexSearcherHolder.StringCollectionValue> >();
                }

                foreach (var readerFacetInfo in returnedReaders)
                {
                    var termsForField = IndexedTerms.GetTermsAndDocumentsFor(readerFacetInfo.Reader, readerFacetInfo.DocBase, facet.Name, _indexName, _state);


                    if (facetsByName.TryGetValue(facet.DisplayName, out Dictionary <string, FacetValue> facetValues) == false)
                    {
                        facetsByName[facet.DisplayName] = facetValues = new Dictionary <string, FacetValue>();
                    }

                    foreach (var kvp in termsForField)
                    {
                        if (query.Metadata.IsDistinct)
                        {
                            if (distinctItems.TryGetValue(kvp.Key, out alreadySeen) == false)
                            {
                                alreadySeen            = new HashSet <IndexSearcherHolder.StringCollectionValue>();
                                distinctItems[kvp.Key] = alreadySeen;
                            }
                        }

                        var needToApplyAggregation = (facet.Aggregation == FacetAggregation.None || facet.Aggregation == FacetAggregation.Count) == false;
                        var intersectedDocuments   = GetIntersectedDocuments(new ArraySegment <int>(kvp.Value), readerFacetInfo.Results, alreadySeen, query, fieldsHash, needToApplyAggregation, context);
                        var intersectCount         = intersectedDocuments.Count;
                        if (intersectCount == 0)
                        {
                            continue;
                        }

                        if (facetValues.TryGetValue(kvp.Key, out FacetValue facetValue) == false)
                        {
                            facetValue = new FacetValue
                            {
                                Range = FacetedQueryHelper.GetRangeName(facet.Name, kvp.Key)
                            };
                            facetValues.Add(kvp.Key, facetValue);
                        }
                        facetValue.Hits += intersectCount;
                        facetValue.Count = facetValue.Hits;

                        if (needToApplyAggregation)
                        {
                            var docsInQuery = new ArraySegment <int>(intersectedDocuments.Documents, 0, intersectedDocuments.Count);
                            ApplyAggregation(facet, facetValue, docsInQuery, readerFacetInfo.Reader, readerFacetInfo.DocBase, _state);
                        }
                    }
                }
            }

            foreach (var range in rangeFacets)
            {
                var facet = defaultFacets[range.Key];
                var needToApplyAggregation = (facet.Aggregation == FacetAggregation.None || facet.Aggregation == FacetAggregation.Count) == false;

                Dictionary <string, HashSet <IndexSearcherHolder.StringCollectionValue> > distinctItems = null;
                HashSet <IndexSearcherHolder.StringCollectionValue> alreadySeen = null;
                if (query.Metadata.IsDistinct)
                {
                    distinctItems = new Dictionary <string, HashSet <IndexSearcherHolder.StringCollectionValue> >();
                }

                foreach (var readerFacetInfo in returnedReaders)
                {
                    var termsForField = IndexedTerms.GetTermsAndDocumentsFor(readerFacetInfo.Reader, readerFacetInfo.DocBase, facet.Name, _indexName, _state);
                    if (query.Metadata.IsDistinct)
                    {
                        if (distinctItems.TryGetValue(range.Key, out alreadySeen) == false)
                        {
                            alreadySeen = new HashSet <IndexSearcherHolder.StringCollectionValue>();
                            distinctItems[range.Key] = alreadySeen;
                        }
                    }

                    var facetResult = results[range.Key];
                    var ranges      = range.Value;
                    foreach (var kvp in termsForField)
                    {
                        for (int i = 0; i < ranges.Count; i++)
                        {
                            var parsedRange = ranges[i];
                            if (parsedRange.IsMatch(kvp.Key))
                            {
                                var facetValue = facetResult.Values[i];

                                var intersectedDocuments = GetIntersectedDocuments(new ArraySegment <int>(kvp.Value), readerFacetInfo.Results, alreadySeen, query, fieldsHash, needToApplyAggregation, context);
                                var intersectCount       = intersectedDocuments.Count;
                                if (intersectCount == 0)
                                {
                                    continue;
                                }

                                facetValue.Hits += intersectCount;
                                facetValue.Count = facetValue.Hits;

                                if (needToApplyAggregation)
                                {
                                    var docsInQuery = new ArraySegment <int>(intersectedDocuments.Documents, 0, intersectedDocuments.Count);
                                    ApplyAggregation(facet, facetValue, docsInQuery, readerFacetInfo.Reader, readerFacetInfo.DocBase, _state);
                                    IntArraysPool.Instance.FreeArray(intersectedDocuments.Documents);
                                    intersectedDocuments.Documents = null;
                                }
                            }
                        }
                    }
                }
            }

            UpdateFacetResults(results, query, defaultFacets, facetsByName);

            CompleteFacetCalculationsStage(results, defaultFacets);

            foreach (var readerFacetInfo in returnedReaders)
            {
                IntArraysPool.Instance.FreeArray(readerFacetInfo.Results.Array);
            }

            return(results);
        }