Exemplo n.º 1
0
            public void Execute()
            {
                ValidateFacets();


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

                bool isDistinct = IndexQuery.IsDistinct;

                if (isDistinct)
                {
                    _fieldsCrc = IndexQuery.FieldsToFetch.Aggregate <string, uint>(0, (current, field) => Crc.Value(field, current));
                }

                _currentState = Database.IndexStorage.GetCurrentStateHolder(Index);
                using (_currentState)
                {
                    var currentIndexSearcher = _currentState.IndexSearcher;

                    var baseQuery       = Database.IndexStorage.GetDocumentQuery(Index, IndexQuery, Database.IndexQueryTriggers);
                    var returnedReaders = GetQueryMatchingDocuments(currentIndexSearcher, baseQuery);

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

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

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

                            Dictionary <string, FacetValue> facetValues;

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

                            foreach (var kvp in termsForField)
                            {
                                if (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, needToApplyAggregation);
                                var intersectCount         = intersectedDocuments.Count;
                                if (intersectCount == 0)
                                {
                                    continue;
                                }

                                FacetValue facetValue;
                                if (facetValues.TryGetValue(kvp.Key, out facetValue) == false)
                                {
                                    facetValue = new FacetValue
                                    {
                                        Range = 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);
                                }
                            }
                        }
                    }

                    foreach (var range in Ranges)
                    {
                        var facet = Facets[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 (isDistinct)
                        {
                            distinctItems = new Dictionary <string, HashSet <IndexSearcherHolder.StringCollectionValue> >();
                        }

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

                            var facetResult = Results.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, needToApplyAggregation);
                                        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);
                                            IntArraysPool.Instance.FreeArray(intersectedDocuments.Documents);
                                            intersectedDocuments.Documents = null;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    UpdateFacetResults(facetsByName);

                    CompleteFacetCalculationsStage();

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