protected static EnsureInvariantCulture ( ) : IDisposable | ||
return | IDisposable |
public IEnumerable <IndexQueryResult> Query() { using (IndexStorage.EnsureInvariantCulture()) { AssertQueryDoesNotContainFieldsThatAreNotIndexes(); IndexSearcher indexSearcher; using (parent.GetSearcher(out indexSearcher)) { var luceneQuery = GetLuceneQuery(); foreach (var indexQueryTrigger in indexQueryTriggers) { luceneQuery = indexQueryTrigger.Value.ProcessQuery(parent.name, luceneQuery, indexQuery); } int start = indexQuery.Start; int pageSize = indexQuery.PageSize; int returnedResults = 0; int skippedResultsInCurrentLoop = 0; do { if (skippedResultsInCurrentLoop > 0) { start = start + pageSize; // trying to guesstimate how many results we will need to read from the index // to get enough unique documents to match the page size pageSize = skippedResultsInCurrentLoop * indexQuery.PageSize; skippedResultsInCurrentLoop = 0; } TopDocs search = ExecuteQuery(indexSearcher, luceneQuery, start, pageSize, indexQuery); indexQuery.TotalSize.Value = search.TotalHits; RecordResultsAlreadySeenForDistinctQuery(indexSearcher, search, start); for (int i = start; i < search.TotalHits && (i - start) < pageSize; i++) { Document document = indexSearcher.Doc(search.ScoreDocs[i].doc); IndexQueryResult indexQueryResult = parent.RetrieveDocument(document, fieldsToFetch, search.ScoreDocs[i].score); if (ShouldIncludeInResults(indexQueryResult) == false) { indexQuery.SkippedResults.Value++; skippedResultsInCurrentLoop++; continue; } returnedResults++; yield return(indexQueryResult); if (returnedResults == indexQuery.PageSize) { yield break; } } } while (skippedResultsInCurrentLoop > 0 && returnedResults < indexQuery.PageSize); } } }
public IEnumerable <IndexQueryResult> IntersectionQuery() { using (IndexStorage.EnsureInvariantCulture()) { AssertQueryDoesNotContainFieldsThatAreNotIndexes(); IndexSearcher indexSearcher; using (parent.GetSearcher(out indexSearcher)) { var subQueries = indexQuery.Query.Split(new[] { Constants.IntersectSeperator }, StringSplitOptions.RemoveEmptyEntries); if (subQueries.Length <= 1) { throw new InvalidOperationException("Invalid INTRESECT query, must have multiple intersect clauses."); } //Not sure how to select the page size here??? The problem is that only docs in this search can be part //of the final result because we're doing an intersection query (but we might exclude some of them) int pageSizeBestGuess = (indexQuery.Start + indexQuery.PageSize) * 2; int intersectMatches = 0, skippedResultsInCurrentLoop = 0; int previousBaseQueryMatches = 0, currentBaseQueryMatches = 0; var firstSubLuceneQuery = ApplyIndexTriggers(GetLuceneQuery(subQueries[0], indexQuery.DefaultField)); //Do the first sub-query in the normal way, so that sorting, filtering etc is accounted for var search = ExecuteQuery(indexSearcher, firstSubLuceneQuery, 0, pageSizeBestGuess, indexQuery); currentBaseQueryMatches = search.ScoreDocs.Length; var intersectionCollector = new IntersectionCollector(indexSearcher, search.ScoreDocs); do { if (skippedResultsInCurrentLoop > 0) { // We get here because out first attempt didn't get enough docs (after INTERSECTION was calculated) pageSizeBestGuess = pageSizeBestGuess * 2; search = ExecuteQuery(indexSearcher, firstSubLuceneQuery, 0, pageSizeBestGuess, indexQuery); previousBaseQueryMatches = currentBaseQueryMatches; currentBaseQueryMatches = search.ScoreDocs.Length; intersectionCollector = new IntersectionCollector(indexSearcher, search.ScoreDocs); } for (int i = 1; i < subQueries.Length; i++) { var luceneSubQuery = ApplyIndexTriggers(GetLuceneQuery(subQueries[i], indexQuery.DefaultField)); indexSearcher.Search(luceneSubQuery, null, intersectionCollector); } var currentIntersectResults = intersectionCollector.DocumentsIdsForCount(subQueries.Length).ToList(); intersectMatches = currentIntersectResults.Count; skippedResultsInCurrentLoop = pageSizeBestGuess - intersectMatches; } while (intersectMatches < indexQuery.PageSize && //stop if we've got enough results to satisfy the pageSize currentBaseQueryMatches < search.TotalHits && //stop if increasing the page size wouldn't make any difference previousBaseQueryMatches < currentBaseQueryMatches); //stop if increasing the page size didn't result in any more "base query" results var intersectResults = intersectionCollector.DocumentsIdsForCount(subQueries.Length).ToList(); //It's hard to know what to do here, the TotalHits from the base search isn't really the TotalSize, //because it's before the INTERSECTION has been applied, so only some of those results make it out. //Trying to give an accurate answer is going to be too costly, so we aren't going to try. indexQuery.TotalSize.Value = search.TotalHits; indexQuery.SkippedResults.Value = skippedResultsInCurrentLoop; //Using the final set of results in the intersectionCollector int returnedResults = 0; for (int i = indexQuery.Start; i < intersectResults.Count && (i - indexQuery.Start) < pageSizeBestGuess; i++) { Document document = indexSearcher.Doc(intersectResults[i].LuceneId); IndexQueryResult indexQueryResult = parent.RetrieveDocument(document, fieldsToFetch, search.ScoreDocs[i].score); if (ShouldIncludeInResults(indexQueryResult) == false) { indexQuery.SkippedResults.Value++; skippedResultsInCurrentLoop++; continue; } returnedResults++; yield return(indexQueryResult); if (returnedResults == indexQuery.PageSize) { yield break; } } } } }