private IEnumerable <FacetMatch> FindMatchesInQuery(Query baseQueryWithoutFacetDrilldown, IList <FacetFieldInfo> allFacetFieldInfos, FacetFieldInfo facetFieldInfoToCalculateFor)
        {
            var calculations = 0;

            var queryFilter = new CachingWrapperFilter(new QueryWrapperFilter(CreateFacetedQuery(baseQueryWithoutFacetDrilldown, allFacetFieldInfos, facetFieldInfoToCalculateFor.FieldName)));
            var bitsQueryWithoutFacetDrilldown     = new OpenBitSetDISI(queryFilter.GetDocIdSet(IndexReader).Iterator(), IndexReader.MaxDoc);
            var baseQueryWithoutFacetDrilldownCopy = new OpenBitSetDISI(bitsQueryWithoutFacetDrilldown.Bits.Length)
            {
                Bits = new long[bitsQueryWithoutFacetDrilldown.Bits.Length]
            };

            var calculatedFacetCounts = new ResultCollection(facetFieldInfoToCalculateFor);

            foreach (var facetValueBitSet in GetOrCreateFacetBitSet(facetFieldInfoToCalculateFor.FieldName).FacetValueBitSetList)
            {
                var isSelected = calculatedFacetCounts.IsSelected(facetValueBitSet.Value);

                if (!isSelected && facetValueBitSet.Count < calculatedFacetCounts.MinCountForNonSelected) //Impossible to get a better result
                {
                    if (calculatedFacetCounts.HaveEnoughResults)
                    {
                        break;
                    }
                }

                bitsQueryWithoutFacetDrilldown.Bits.CopyTo(baseQueryWithoutFacetDrilldownCopy.Bits, 0);
                baseQueryWithoutFacetDrilldownCopy.NumWords = bitsQueryWithoutFacetDrilldown.NumWords;

                var bitset = facetValueBitSet.Bitset ?? CalculateOpenBitSetDisi(facetFieldInfoToCalculateFor.FieldName, facetValueBitSet.Value);
                baseQueryWithoutFacetDrilldownCopy.And(bitset);
                var count = baseQueryWithoutFacetDrilldownCopy.Cardinality();
                if (count == 0)
                {
                    continue;
                }
                var match = new FacetMatch
                {
                    Count          = count,
                    Value          = facetValueBitSet.Value,
                    FacetFieldName = facetFieldInfoToCalculateFor.FieldName
                };

                calculations++;
                if (isSelected)
                {
                    calculatedFacetCounts.AddToSelected(match);
                }
                else
                {
                    calculatedFacetCounts.AddToNonSelected(match);
                }
            }

            return(calculatedFacetCounts.GetList());
        }
예제 #2
0
        /// <summary>
        /// Creates facets.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="query">The query.</param>
        private void CreateFacets(IndexReader reader, Query query)
        {
            var groups          = new List <FacetGroup>();
            var baseQueryFilter = new CachingWrapperFilter(new QueryWrapperFilter(query));
            var baseDocIdSet    = baseQueryFilter.GetDocIdSet(reader);

            #region Subcategory filters


            /*
             * var catalogCriteria = Results.SearchCriteria as CatalogItemSearchCriteria;
             * if (catalogCriteria != null && catalogCriteria.ChildCategoryFilters.Any())
             * {
             *  var group = new FacetGroup("Subcategory");
             *  var groupCount = 0;
             *
             *  foreach (var value in catalogCriteria.ChildCategoryFilters)
             *  {
             *      var q = LuceneQueryHelper.CreateQuery(catalogCriteria.OutlineField, value);
             *
             *      if (q == null) continue;
             *
             *      var queryFilter = new CachingWrapperFilter(new QueryWrapperFilter(q));
             *      var filterArray = queryFilter.GetDocIdSet(reader);
             *      var newCount = (int)CalculateFacetCount(baseDocIdSet, filterArray);
             *      if (newCount == 0) continue;
             *
             *      var newFacet = new Facet(group, value.Code, value.Name, newCount);
             *      group.Facets.Add(newFacet);
             *      groupCount += newCount;
             *  }
             *
             *  // Add only if items exist under
             *  if (groupCount > 0)
             *  {
             *      groups.Add(group);
             *  }
             * }
             * */

            #endregion

            if (Results.SearchCriteria.Filters != null && Results.SearchCriteria.Filters.Length > 0)
            {
                foreach (var filter in Results.SearchCriteria.Filters)
                {
                    if (!string.IsNullOrEmpty(Results.SearchCriteria.Currency) && filter is PriceRangeFilter)
                    {
                        var valCurrency = ((PriceRangeFilter)filter).Currency;
                        if (!valCurrency.Equals(Results.SearchCriteria.Currency, StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }
                    }

                    var facetGroup = CalculateResultCount(reader, baseDocIdSet, filter, Results.SearchCriteria);
                    if (facetGroup != null)
                    {
                        groups.Add(facetGroup);
                    }
                }
            }

            Results.FacetGroups = groups.ToArray();
        }
        /// <summary>
        /// Creates facets.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="query">The query.</param>
        private void CreateFacets(IndexReader reader, Query query)
        {
            var groups = new List<FacetGroup>();
            var baseQueryFilter = new CachingWrapperFilter(new QueryWrapperFilter(query));
            var baseDocIdSet = baseQueryFilter.GetDocIdSet(reader);

            #region Subcategory filters

           
            /* 
            var catalogCriteria = Results.SearchCriteria as CatalogItemSearchCriteria;
            if (catalogCriteria != null && catalogCriteria.ChildCategoryFilters.Any())
            {
                var group = new FacetGroup("Subcategory");
                var groupCount = 0;

                foreach (var value in catalogCriteria.ChildCategoryFilters)
                {
                    var q = LuceneQueryHelper.CreateQuery(catalogCriteria.OutlineField, value);

                    if (q == null) continue;

                    var queryFilter = new CachingWrapperFilter(new QueryWrapperFilter(q));
                    var filterArray = queryFilter.GetDocIdSet(reader);
                    var newCount = (int)CalculateFacetCount(baseDocIdSet, filterArray);
                    if (newCount == 0) continue;

                    var newFacet = new Facet(group, value.Code, value.Name, newCount);
                    group.Facets.Add(newFacet);
                    groupCount += newCount;
                }

                // Add only if items exist under
                if (groupCount > 0)
                {
                    groups.Add(group);
                }
            }
             * */

            #endregion

            if (Results.SearchCriteria.Filters != null && Results.SearchCriteria.Filters.Length > 0)
            {
                foreach (var filter in Results.SearchCriteria.Filters)
                {
                    var group = new FacetGroup(filter.Key);
                    var groupCount = 0;

                    if (!String.IsNullOrEmpty(Results.SearchCriteria.Currency) && filter is s.PriceRangeFilter)
                    {
                        var valCurrency = ((s.PriceRangeFilter) filter).Currency;
                        if (
                            !valCurrency.Equals(
                                Results.SearchCriteria.Currency, StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }
                    }

                    groupCount += CalculateResultCount(reader, baseDocIdSet, group, filter,
                        Results.SearchCriteria);

                    // Add only if items exist under
                    if (groupCount > 0)
                    {
                        groups.Add(group);
                    }
                }
            }

            Results.FacetGroups = groups.ToArray();
        }
        /// <summary>
        /// Creates facets.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="query">The query.</param>
        private void CreateFacets(IndexReader reader, Query query)
        {
            var groups = new List<FacetGroup>();

            if (this.Results.SearchCriteria.Filters != null && this.Results.SearchCriteria.Filters.Length > 0)
            {
                var baseQueryFilter = new CachingWrapperFilter(new QueryWrapperFilter(query));

                var baseBitArray = baseQueryFilter.GetDocIdSet(reader);
                foreach (var filter in this.Results.SearchCriteria.Filters)
                {
                    var group = new FacetGroup(filter.Key);

                    var groupCount = 0;

                    if (!String.IsNullOrEmpty(this.Results.SearchCriteria.Currency) && filter is s.PriceRangeFilter)
                    {
                        var valCurrency = ((s.PriceRangeFilter)filter).Currency;
                        if (
                            !valCurrency.Equals(
                                this.Results.SearchCriteria.Currency, StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }
                    }

                    groupCount += this.CalculateResultCount(
                        reader, baseBitArray, group, filter, this.Results.SearchCriteria.Currency);

                    // Add only if items exist under
                    if (groupCount > 0)
                    {
                        groups.Add(group);
                    }
                }
            }

            this.Results.FacetGroups = groups.ToArray();
        }
        /// <summary>
        /// Calculates the result count.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="baseDocIdSet">The base doc id set.</param>
        /// <param name="facetGroup">The facet group.</param>
        /// <param name="filter">The filter.</param>
        /// <param name="currency">The currency.</param>
        /// <returns></returns>
        private int CalculateResultCount(
            IndexReader reader, DocIdSet baseDocIdSet, FacetGroup facetGroup, ISearchFilter filter, string currency)
        {
            var count = 0;

            ISearchFilterValue[] values = null;
            var priceQuery = false;
            if (filter is s.AttributeFilter)
            {
                values = ((s.AttributeFilter)filter).Values;
            }
            else if (filter is s.RangeFilter)
            {
                values = ((s.RangeFilter)filter).Values;
            }
            else if (filter is s.PriceRangeFilter)
            {
                values = ((s.PriceRangeFilter)filter).Values;
                priceQuery = true;
            }

            if (values == null)
            {
                return 0;
            }

            foreach (var value in values)
            {
                Query q = null;
                if (priceQuery)
                {
                    q = LuceneQueryHelper.CreateQuery(
                        this.Results.SearchCriteria, filter.Key, value as s.RangeFilterValue);
                }
                else
                {
                    q = LuceneQueryHelper.CreateQuery(filter.Key, value);
                }

                if (q == null) continue;

                var queryFilter = new CachingWrapperFilter(new QueryWrapperFilter(q));
                var filterArray = queryFilter.GetDocIdSet(reader);
                var newCount = (int)this.CalculateFacetCount(baseDocIdSet, filterArray);
                if (newCount == 0) continue;

                var newFacet = new Facet(facetGroup, value.Id, this.GetDescription(value, this.Results.SearchCriteria.Locale), newCount);
                facetGroup.Facets.Add(newFacet);
                count += newCount;
            }

            return count;
        }
예제 #6
0
        public IEnumerable <IHit> Query(int pageIndex, int pageSize, out int totalCount, out IEnumerable <FacetGroup> facetedResults)
        {
            totalCount     = 0;
            facetedResults = null;

            if (searchPaths == null || searchPaths.Count <= 0)
            {
                searchPaths.AddRange(indexPaths.Values.Select(o => o.Path));
            }

            List <LuceneHit> results = new List <LuceneHit>();

            List <IndexSearcher> subSearchs = new List <IndexSearcher>();

            searchPaths.ForEach(o => subSearchs.Add(new IndexSearcher(FSDirectory.Open(o))));

            if (facetFields != null && facetFields.Count > 0)
            {
                var         facetGroups     = new List <FacetGroup>();
                var         mainQueryFilter = new CachingWrapperFilter(new QueryWrapperFilter(query));
                MultiReader readers         = new MultiReader(subSearchs.Select(o => o.IndexReader).ToArray());

                foreach (var facetField in facetFields)
                {
                    FacetGroup fg = new FacetGroup();
                    fg.FieldName = facetFieldNameProvider.GetMapName(TypeName, facetField);
                    var items = new List <FacetItem>();

                    var allDistinctField = FieldCache_Fields.DEFAULT.GetStrings(readers, facetField).Distinct().ToArray();
                    int totalHits        = 0;

                    Parallel.ForEach(allDistinctField, fieldValue =>
                    {
                        //foreach (var fieldValue in allDistinctField)
                        //{
                        var facetQuery       = new TermQuery(new Term(facetField, fieldValue));
                        var facetQueryFilter = new CachingWrapperFilter(new QueryWrapperFilter(facetQuery));

                        var bs = new OpenBitSetDISI(facetQueryFilter.GetDocIdSet(readers).Iterator(), readers.MaxDoc);
                        bs.InPlaceAnd(mainQueryFilter.GetDocIdSet(readers).Iterator());
                        int count = (Int32)bs.Cardinality();

                        FacetItem item  = new FacetItem();
                        item.GroupValue = fieldValue;
                        item.Count      = count;

                        items.Add(item);
                        totalHits += count;
                    }
                                     );

                    fg.FacetItems = items.OrderByDescending(o => o.Count);
                    fg.TotalHits  = totalHits;

                    facetGroups.Add(fg);
                }

                facetedResults = facetGroups.OrderBy(o => o.FieldName);
            }
            ParallelMultiSearcher searcher = new ParallelMultiSearcher(subSearchs.ToArray());
            Sort sort = null;

            if (sortFields != null && sortFields.Count > 0)
            {
                sort = new Sort(sortFields.ToArray());
            }

            int maxDoc     = searcher.MaxDoc;
            int startIndex = 0;

            if (pageIndex >= 0 && pageSize > 0)
            {
                startIndex = pageIndex * pageSize;
                maxDoc     = pageSize * (pageIndex + 1);
            }
            var docs = sort == null?searcher.Search(query, null, maxDoc) : searcher.Search(query, null, maxDoc, sort);

            totalCount = docs.TotalHits;
            int endIndex = docs.TotalHits - startIndex;

            for (int i = startIndex; i < endIndex; i++)
            {
                LuceneHit h = new LuceneHit(TypeName, DocumentBuilder, searcher.Doc(docs.ScoreDocs[i].Doc));
                results.Add(h);
            }
            return(results);
        }