public override TopFieldDocs Search(Weight weight, Filter filter, int n, Sort sort) { throw new System.NotSupportedException(); }
public override TopFieldDocs Search(Weight weight, Filter filter, int n, Sort sort) { FieldDocSortedHitQueue hq = null; int totalHits = 0; float maxScore = System.Single.NegativeInfinity; for (int i = 0; i < searchables.Length; i++) { // search each searcher TopFieldDocs docs = searchables[i].Search(weight, filter, n, sort); // If one of the Sort fields is FIELD_DOC, need to fix its values, so that // it will break ties by doc Id properly. Otherwise, it will compare to // 'relative' doc Ids, that belong to two different searchers. for (int j = 0; j < docs.fields.Length; j++) { if (docs.fields[j].GetType() == SortField.DOC) { // iterate over the score docs and change their fields value for (int j2 = 0; j2 < docs.ScoreDocs.Length; j2++) { FieldDoc fd = (FieldDoc) docs.ScoreDocs[j2]; fd.fields[j] = (System.Int32) (((System.Int32) fd.fields[j]) + starts[i]); } break; } } if (hq == null) hq = new FieldDocSortedHitQueue(docs.fields, n); totalHits += docs.TotalHits; // update totalHits maxScore = System.Math.Max(maxScore, docs.GetMaxScore()); ScoreDoc[] scoreDocs = docs.ScoreDocs; for (int j = 0; j < scoreDocs.Length; j++) { // merge scoreDocs into hq ScoreDoc scoreDoc = scoreDocs[j]; scoreDoc.doc += starts[i]; // convert doc if (!hq.Insert(scoreDoc)) break; // no more scores > minScore } } ScoreDoc[] scoreDocs2 = new ScoreDoc[hq.Size()]; for (int i = hq.Size() - 1; i >= 0; i--) // put docs in array scoreDocs2[i] = (ScoreDoc) hq.Pop(); return new TopFieldDocs(totalHits, scoreDocs2, hq.GetFields(), maxScore); }
/// <summary>Construct to collect a given number of hits.</summary> /// <param name="reader">the index to be searched /// </param> /// <param name="sort">the sort criteria /// </param> /// <param name="numHits">the maximum number of hits to collect /// </param> public TopFieldDocCollector(IndexReader reader, Sort sort, int numHits):base(new FieldSortedHitQueue(reader, sort.fields, numHits)) { }
/// <summary> Creates a new {@link TopFieldCollector} from the given /// arguments. /// /// <p/><b>NOTE</b>: The instances returned by this method /// pre-allocate a full array of length /// <code>numHits</code>. /// /// </summary> /// <param name="sort">the sort criteria (SortFields). /// </param> /// <param name="numHits">the number of results to collect. /// </param> /// <param name="fillFields">specifies whether the actual field values should be returned on /// the results (FieldDoc). /// </param> /// <param name="trackDocScores">specifies whether document scores should be tracked and set on the /// results. Note that if set to false, then the results' scores will /// be set to Float.NaN. Setting this to true affects performance, as /// it incurs the score computation on each competitive result. /// Therefore if document scores are not required by the application, /// it is recommended to set it to false. /// </param> /// <param name="trackMaxScore">specifies whether the query's maxScore should be tracked and set /// on the resulting {@link TopDocs}. Note that if set to false, /// {@link TopDocs#GetMaxScore()} returns Float.NaN. Setting this to /// true affects performance as it incurs the score computation on /// each result. Also, setting this true automatically sets /// <code>trackDocScores</code> to true as well. /// </param> /// <param name="docsScoredInOrder">specifies whether documents are scored in doc Id order or not by /// the given {@link Scorer} in {@link #SetScorer(Scorer)}. /// </param> /// <returns> a {@link TopFieldCollector} instance which will sort the results by /// the sort criteria. /// </returns> /// <throws> IOException </throws> public static TopFieldCollector create(Sort sort, int numHits, bool fillFields, bool trackDocScores, bool trackMaxScore, bool docsScoredInOrder) { if (sort.fields.Length == 0) { throw new System.ArgumentException("Sort must contain at least one field"); } FieldValueHitQueue queue = FieldValueHitQueue.Create(sort.fields, numHits); if (queue.GetComparators().Length == 1) { if (docsScoredInOrder) { if (trackMaxScore) { return new OneComparatorScoringMaxScoreCollector(queue, numHits, fillFields); } else if (trackDocScores) { return new OneComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields); } else { return new OneComparatorNonScoringCollector(queue, numHits, fillFields); } } else { if (trackMaxScore) { return new OutOfOrderOneComparatorScoringMaxScoreCollector(queue, numHits, fillFields); } else if (trackDocScores) { return new OutOfOrderOneComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields); } else { return new OutOfOrderOneComparatorNonScoringCollector(queue, numHits, fillFields); } } } // multiple comparators. if (docsScoredInOrder) { if (trackMaxScore) { return new MultiComparatorScoringMaxScoreCollector(queue, numHits, fillFields); } else if (trackDocScores) { return new MultiComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields); } else { return new MultiComparatorNonScoringCollector(queue, numHits, fillFields); } } else { if (trackMaxScore) { return new OutOfOrderMultiComparatorScoringMaxScoreCollector(queue, numHits, fillFields); } else if (trackDocScores) { return new OutOfOrderMultiComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields); } else { return new OutOfOrderMultiComparatorNonScoringCollector(queue, numHits, fillFields); } } }
static Sort() { INDEXORDER = new Sort(SortField.FIELD_DOC); }
internal Hits(Searcher s, Query q, Filter f, Sort o) { weight = q.Weight(s); searcher = s; filter = f; sort = o; nDeletions = CountDeletions(s); GetMoreDocs(50); // retrieve 100 initially lengthAtStart = length; }
public override TopFieldDocs Search(Weight weight, Filter filter, int nDocs, Sort sort) { return Search(weight, filter, nDocs, sort, true); }
/// <summary> Just like {@link #Search(Weight, Filter, int, Sort)}, but you choose /// whether or not the fields in the returned {@link FieldDoc} instances /// should be set by specifying fillFields.<br/> /// /// <p/> /// NOTE: this does not compute scores by default. If you need scores, create /// a {@link TopFieldCollector} instance by calling /// {@link TopFieldCollector#create} and then pass that to /// {@link #Search(Weight, Filter, Collector)}. /// <p/> /// </summary> public virtual TopFieldDocs Search(Weight weight, Filter filter, int nDocs, Sort sort, bool fillFields) { nDocs = System.Math.Min(nDocs, reader.MaxDoc()); SortField[] fields = sort.fields; bool legacy = false; for (int i = 0; i < fields.Length; i++) { SortField field = fields[i]; System.String fieldname = field.GetField(); int type = field.GetType(); // Resolve AUTO into its true type if (type == SortField.AUTO) { int autotype = SortField.DetectFieldType(reader, fieldname); if (autotype == SortField.STRING) { fields[i] = new SortField(fieldname, field.GetLocale(), field.GetReverse()); } else { fields[i] = new SortField(fieldname, autotype, field.GetReverse()); } } if (field.GetUseLegacySearch()) { legacy = true; } } if (legacy) { // Search the single top-level reader TopDocCollector collector = new TopFieldDocCollector(reader, sort, nDocs); HitCollectorWrapper hcw = new HitCollectorWrapper(collector); hcw.SetNextReader(reader, 0); if (filter == null) { Scorer scorer = weight.Scorer(reader, true, true); if (scorer != null) { scorer.Score(hcw); } } else { SearchWithFilter(reader, weight, filter, hcw); } return (TopFieldDocs) collector.TopDocs(); } TopFieldCollector collector2 = TopFieldCollector.create(sort, nDocs, fillFields, fieldSortDoTrackScores, fieldSortDoMaxScore, !weight.ScoresDocsOutOfOrder()); Search(weight, filter, collector2); return (TopFieldDocs) collector2.TopDocs(); }
public virtual Hits Search(Query query, Sort sort) { return new Hits(this, query, null, sort); }
public virtual Hits Search(Query query, Filter filter, Sort sort) { return new Hits(this, query, filter, sort); }
abstract public TopFieldDocs Search(Weight weight, Filter filter, int n, Sort sort);
/// <summary>Search implementation with arbitrary sorting. Finds /// the top <code>n</code> hits for <code>query</code>, applying /// <code>filter</code> if non-null, and sorting the hits by the criteria in /// <code>sort</code>. /// /// <p/>NOTE: this does not compute scores by default; use /// {@link IndexSearcher#setDefaultFieldSortScoring} to enable scoring. /// /// </summary> /// <throws> BooleanQuery.TooManyClauses </throws> public virtual TopFieldDocs Search(Query query, Filter filter, int n, Sort sort) { return Search(CreateWeight(query), filter, n, sort); }
public MultiSearcherThread(Searchable searchable, Weight weight, Filter filter, int nDocs, FieldDocSortedHitQueue hq, Sort sort, int i, int[] starts, System.String name):base(name) { this.searchable = searchable; this.weight = weight; this.filter = filter; this.nDocs = nDocs; this.hq = hq; this.i = i; this.starts = starts; this.sort = sort; }
/// <summary> A search implementation allowing sorting which spans a new thread for each /// Searchable, waits for each search to complete and merges /// the results back together. /// </summary> public override TopFieldDocs Search(Weight weight, Filter filter, int nDocs, Sort sort) { // don't specify the fields - we'll wait to do this until we get results FieldDocSortedHitQueue hq = new FieldDocSortedHitQueue(null, nDocs); int totalHits = 0; MultiSearcherThread[] msta = new MultiSearcherThread[searchables.Length]; for (int i = 0; i < searchables.Length; i++) { // search each searchable // Assume not too many searchables and cost of creating a thread is by far inferior to a search msta[i] = new MultiSearcherThread(searchables[i], weight, filter, nDocs, hq, sort, i, starts, "MultiSearcher thread #" + (i + 1)); msta[i].Start(); } float maxScore = System.Single.NegativeInfinity; for (int i = 0; i < searchables.Length; i++) { try { msta[i].Join(); } catch (System.Threading.ThreadInterruptedException ie) { // In 3.0 we will change this to throw // InterruptedException instead SupportClass.ThreadClass.Current().Interrupt(); throw new System.SystemException(ie.Message, ie); } System.IO.IOException ioe = msta[i].GetIOException(); if (ioe == null) { totalHits += msta[i].Hits(); maxScore = System.Math.Max(maxScore, msta[i].GetMaxScore()); } else { // if one search produced an IOException, rethrow it throw ioe; } } ScoreDoc[] scoreDocs = new ScoreDoc[hq.Size()]; for (int i = hq.Size() - 1; i >= 0; i--) // put docs in array scoreDocs[i] = (ScoreDoc) hq.Pop(); return new TopFieldDocs(totalHits, scoreDocs, hq.GetFields(), maxScore); }
/// <summary>Construct to collect a given number of hits.</summary> /// <param name="reader">the index to be searched /// </param> /// <param name="sort">the sort criteria /// </param> /// <param name="numHits">the maximum number of hits to collect /// </param> public TopFieldDocCollector(IndexReader reader, Sort sort, int numHits) : base(new FieldSortedHitQueue(reader, sort.fields, numHits)) { }