/// <summary> Allows redefinition of sort fields if they are <code>null</code>. /// This is to handle the case using ParallelMultiSearcher where the /// original list contains AUTO and we don't know the actual sort /// type until the values come back. The fields can only be set once. /// This method is thread safe. /// </summary> /// <param name="fields"> /// </param> internal virtual void SetFields(SortField[] fields) { lock (this) { if (this.fields == null) { this.fields = fields; this.collators = HasCollators(fields); } } }
public OneComparatorFieldValueHitQueue(SortField[] fields, int size):base(fields) { if (fields.Length == 0) { throw new System.ArgumentException("Sort must contain at least one field"); } SortField field = fields[0]; // AUTO is resolved before we are called System.Diagnostics.Debug.Assert(field.GetType() != SortField.AUTO); comparator = field.GetComparator(size, 0); oneReverseMul = field.reverse?- 1:1; comparators[0] = comparator; reverseMul[0] = oneReverseMul; Initialize(size); }
/// <summary> Creates a hit queue sorted by the given list of fields.</summary> /// <param name="reader"> Index to use. /// </param> /// <param name="fields">Fieldable names, in priority order (highest priority first). Cannot be <code>null</code> or empty. /// </param> /// <param name="size"> The number of hits to retain. Must be greater than zero. /// </param> /// <throws> IOException </throws> public FieldSortedHitQueue(IndexReader reader, SortField[] fields, int size) { int n = fields.Length; comparators = new ScoreDocComparator[n]; this.fields = new SortField[n]; for (int i = 0; i < n; ++i) { System.String fieldname = fields[i].GetField(); comparators[i] = GetCachedComparator(reader, fieldname, fields[i].GetType(), fields[i].GetParser(), fields[i].GetLocale(), fields[i].GetFactory()); // new SortField instances must only be created when auto-detection is in use if (fields[i].GetType() == SortField.AUTO) { if (comparators[i].SortType() == SortField.STRING) { this.fields[i] = new SortField(fieldname, fields[i].GetLocale(), fields[i].GetReverse()); } else { this.fields[i] = new SortField(fieldname, comparators[i].SortType(), fields[i].GetReverse()); } } else { System.Diagnostics.Debug.Assert(comparators [i].SortType() == fields [i].GetType()); this.fields[i] = fields[i]; } } Initialize(size); }
/// <summary> Creates a hit queue sorted by the given list of fields. /// /// <p/><b>NOTE</b>: The instances returned by this method /// pre-allocate a full array of length <code>numHits</code>. /// /// </summary> /// <param name="fields">SortField array we are sorting by in priority order (highest /// priority first); cannot be <code>null</code> or empty /// </param> /// <param name="size">The number of hits to retain. Must be greater than zero. /// </param> /// <throws> IOException </throws> public static FieldValueHitQueue Create(SortField[] fields, int size) { if (fields.Length == 0) { throw new System.ArgumentException("Sort must contain at least one field"); } if (fields.Length == 1) { return new OneComparatorFieldValueHitQueue(fields, size); } else { return new MultiComparatorsFieldValueHitQueue(fields, size); } }
// prevent instantiation and extension. private FieldValueHitQueue(SortField[] fields) { // When we get here, fields.length is guaranteed to be > 0, therefore no // need to check it again. // All these are required by this class's API - need to return arrays. // Therefore even in the case of a single comparator, create an array // anyway. this.fields = fields; int numComparators = fields.Length; comparators = new FieldComparator[numComparators]; reverseMul = new int[numComparators]; }
public MultiComparatorsFieldValueHitQueue(SortField[] fields, int size):base(fields) { int numComparators = comparators.Length; for (int i = 0; i < numComparators; ++i) { SortField field = fields[i]; // AUTO is resolved before we are called System.Diagnostics.Debug.Assert(field.GetType() != SortField.AUTO); reverseMul[i] = field.reverse?- 1:1; comparators[i] = field.GetComparator(size, i); } Initialize(size); }
/// <summary>Returns an array of collators, possibly <code>null</code>. The collators /// correspond to any SortFields which were given a specific locale. /// </summary> /// <param name="fields">Array of sort fields. /// </param> /// <returns> Array, possibly <code>null</code>. /// </returns> private System.Globalization.CompareInfo[] HasCollators(SortField[] fields) { if (fields == null) return null; System.Globalization.CompareInfo[] ret = new System.Globalization.CompareInfo[fields.Length]; for (int i = 0; i < fields.Length; ++i) { System.Globalization.CultureInfo locale = fields[i].GetLocale(); if (locale != null) ret[i] = locale.CompareInfo; } return ret; }
/// <summary> Creates a hit queue sorted by the given list of fields.</summary> /// <param name="fields">Fieldable names, in priority order (highest priority first). /// </param> /// <param name="size"> The number of hits to retain. Must be greater than zero. /// </param> internal FieldDocSortedHitQueue(SortField[] fields, int size) { this.fields = fields; this.collators = HasCollators(fields); Initialize(size); }
/// <summary>Sets the sort to the given criteria. </summary> public virtual void SetSort(SortField field) { this.fields = new SortField[]{field}; }
/// <summary>Sets the sort to the given criteria in succession. </summary> public virtual void SetSort(SortField[] fields) { this.fields = fields; }
public virtual void SetSort(System.String[] fieldnames) { int n = fieldnames.Length; SortField[] nfields = new SortField[n]; for (int i = 0; i < n; ++i) { nfields[i] = new SortField(fieldnames[i], SortField.AUTO); } fields = nfields; }
/// <summary>Sorts in succession by the criteria in each SortField. </summary> public Sort(SortField[] fields) { SetSort(fields); }
/// <summary>Sorts by the criteria in the given SortField. </summary> public Sort(SortField field) { SetSort(field); }
/// <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(); }
/// <summary>Creates one of these objects.</summary> /// <param name="totalHits"> Total number of hits for the query. /// </param> /// <param name="scoreDocs"> The top hits for the query. /// </param> /// <param name="fields"> The sort criteria used to find the top hits. /// </param> /// <param name="maxScore"> The maximum score encountered. /// </param> public TopFieldDocs(int totalHits, ScoreDoc[] scoreDocs, SortField[] fields, float maxScore):base(totalHits, scoreDocs, maxScore) { this.fields = fields; }