/// <summary> /// Expert: Low-level search implementation. Finds the top <paramref name="nDocs"/> /// hits for <c>query</c>, applying <c>filter</c> if non-null. /// /// <para/>Applications should usually call <see cref="IndexSearcher.Search(Query,int)"/> or /// <see cref="IndexSearcher.Search(Query,Filter,int)"/> instead. </summary> /// <exception cref="BooleanQuery.TooManyClausesException"> If a query would exceed /// <see cref="BooleanQuery.MaxClauseCount"/> clauses. </exception> protected virtual TopDocs Search(Weight weight, ScoreDoc after, int nDocs) { int limit = reader.MaxDoc; if (limit == 0) { limit = 1; } if (after != null && after.Doc >= limit) { throw new System.ArgumentException("after.doc exceeds the number of documents in the reader: after.doc=" + after.Doc + " limit=" + limit); } nDocs = Math.Min(nDocs, limit); if (executor == null) { return(Search(m_leafContexts, weight, after, nDocs)); } else { HitQueue hq = new HitQueue(nDocs, false); ReentrantLock @lock = new ReentrantLock(); ExecutionHelper <TopDocs> runner = new ExecutionHelper <TopDocs>(executor); for (int i = 0; i < m_leafSlices.Length; i++) // search each sub { runner.Submit(new SearcherCallableNoSort(@lock, this, m_leafSlices[i], weight, after, nDocs, hq)); } int totalHits = 0; float maxScore = float.NegativeInfinity; foreach (TopDocs topDocs in runner) { if (topDocs.TotalHits != 0) { totalHits += topDocs.TotalHits; maxScore = Math.Max(maxScore, topDocs.MaxScore); } } var scoreDocs = new ScoreDoc[hq.Count]; for (int i = hq.Count - 1; i >= 0; i--) // put docs in array { scoreDocs[i] = hq.Pop(); } return(new TopDocs(totalHits, scoreDocs, maxScore)); } }
/// <summary> /// Just like <see cref="Search(Weight, int, Sort, bool, bool)"/>, but you choose /// whether or not the fields in the returned <see cref="FieldDoc"/> instances should /// be set by specifying <paramref name="fillFields"/>. /// </summary> protected virtual TopFieldDocs Search(Weight weight, FieldDoc after, int nDocs, Sort sort, bool fillFields, bool doDocScores, bool doMaxScore) { if (sort == null) { throw new System.ArgumentNullException("Sort must not be null"); } int limit = reader.MaxDoc; if (limit == 0) { limit = 1; } nDocs = Math.Min(nDocs, limit); if (executor == null) { // use all leaves here! return(Search(m_leafContexts, weight, after, nDocs, sort, fillFields, doDocScores, doMaxScore)); } else { TopFieldCollector topCollector = TopFieldCollector.Create(sort, nDocs, after, fillFields, doDocScores, doMaxScore, false); ReentrantLock @lock = new ReentrantLock(); ExecutionHelper <TopFieldDocs> runner = new ExecutionHelper <TopFieldDocs>(executor); for (int i = 0; i < m_leafSlices.Length; i++) // search each leaf slice { runner.Submit(new SearcherCallableWithSort(@lock, this, m_leafSlices[i], weight, after, nDocs, topCollector, sort, doDocScores, doMaxScore)); } int totalHits = 0; float maxScore = float.NegativeInfinity; foreach (TopFieldDocs topFieldDocs in runner) { if (topFieldDocs.TotalHits != 0) { totalHits += topFieldDocs.TotalHits; maxScore = Math.Max(maxScore, topFieldDocs.MaxScore); } } TopFieldDocs topDocs = (TopFieldDocs)topCollector.GetTopDocs(); return(new TopFieldDocs(totalHits, topDocs.ScoreDocs, topDocs.Fields, topDocs.MaxScore)); } }