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()); }
/// <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; }
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); }