/// <summary> /// Searches the Lucene index for Documents that match the specified search criteria. /// </summary> /// <param name="criteria">The search criteria.</param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="System.ArgumentNullException"></exception> public SearchResult<Guid> Search(SearchCriteria criteria) { if (criteria == null) throw new ArgumentNullException(nameof(criteria)); criteria.Query = String.IsNullOrWhiteSpace(criteria.Query) ? ALL_DOCS_QUERY : criteria.Query; criteria.TopN = criteria.TopN > 0 ? criteria.TopN : SearchCriteria.DEFAULT_TOP_N; criteria.ItemsPerPage = criteria.ItemsPerPage > 0 ? criteria.ItemsPerPage : SearchCriteria.DEFAULT_ITEMS_PER_PAGE; criteria.PageNumber = criteria.PageNumber > 0 ? criteria.PageNumber : 1; criteria.Validate(); var result = new SearchResult<Guid>(criteria); var queryParser = new LuceneQueryParser(Schema.StandardField.FULL_TEXT, _compositeAnalyzer, Schema); var query = queryParser.Parse(criteria.Query); var instance = _searcherTaxonomyManager.Acquire() as SearcherTaxonomyManagerSearcherAndTaxonomy; if (instance != null) { var searcher = instance.Searcher; var taxonomyReader = instance.TaxonomyReader; try { var sort = GetSortCriteria(criteria.SortByField); var selectedFacets = criteria.SelectCategories.ToFacetFields(); var topDocs = (TopDocs)null; var categories = (IEnumerable<Category>)null; if (selectedFacets.Count() == 0) { // We are not going to do a drill-down on specific facets. // Instead we will just take the top N facets from the matching Documents. var facetsCollector = new FacetsCollector(); // Get the matching Documents topDocs = FacetsCollector.Search(searcher, query, criteria.TopN, sort, facetsCollector); // Get the Facet counts from the matching Documents var facetCounts = new FastTaxonomyFacetCounts(taxonomyReader, _facetBuilder.FacetsConfig, facetsCollector); categories = facetCounts.GetCategories(criteria.TopNCategories); } else { // Perform a drill-sideways query var drillDownQuery = new DrillDownQuery(_facetBuilder.FacetsConfig, query); foreach (var facetField in selectedFacets) drillDownQuery.Add(facetField.Dim, facetField.Path); var drillSideways = new DrillSideways(searcher, _facetBuilder.FacetsConfig, taxonomyReader); var drillSidewaysResult = drillSideways.Search(drillDownQuery, null, null, criteria.TopN, sort, false, false); // Get the matching documents topDocs = drillSidewaysResult.Hits; // Get the Facet counts from the matching Documents categories = drillSidewaysResult.Facets.GetCategories(criteria.TopNCategories, selectedFacets); } // TODO: Don't pass TopDocs; pass an IEnumerable<Guid> result.PopulateWith(topDocs, categories, id => searcher.Doc(id)); } finally { _searcherTaxonomyManager.Release(instance); searcher = null; taxonomyReader = null; } } return result; }