Created: Feb 11, 2004 1:25:29 PM @since lucene 1.4
/// <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 <c>null</c> 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); }
public Sort ParseSort(string sortSpec) { if (sortSpec == null || sortSpec.Length == 0) return null; string[] parts = sortSep.Split(sortSpec.Trim()); if (parts.Length == 0) return null; SortField[] lst = new SortField[parts.Length]; for (int i = 0; i < parts.Length; i++) { string part = parts[i].Trim(); bool top = true; int idx = part.IndexOf(' '); if (idx > 0) { string order = part.Substring(idx + 1).Trim(); if ("desc".Equals(order) || "top".Equals(order)) { top = true; } else if ("asc".Equals(order) || "bottom".Equals(order)) { top = false; } else { throw new ArgumentException("Unknown sort order: " + order); } part = part.Substring(0, idx).Trim(); } else { throw new ArgumentException("Missing sort order."); } if ("score".Equals(part)) { if (top) { // If thre is only one thing in the list, just do the regular thing... if (parts.Length == 1) { return null; // do normal scoring... } lst[i] = SortField.FIELD_SCORE; } else { lst[i] = new SortField(null, SortField.SCORE, true); } } else { lst[i] = new SortField(part, SortField.STRING, top); } } return new Sort(lst); }
private Hits GetHitsByFiled(string filedname,Analyzer analyzer, string searchStr, IndexSearcher searcher) { MultiFieldQueryParser parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_CURRENT, new string[] { filedname}, analyzer); Query query = parser.Parse(searchStr); Sort sort = new Sort(); SortField f = new SortField("publish_time", SortField.STRING, true);//按照publish_time字段排序,true表示降序 sort.SetSort(f); Hits hits = searcher.Search(query, sort); return hits; }
/// <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 void ApplySort(SortField[] sorts) { if (sorts == null) { _req.ClearSort(); } else { _req.Sort = sorts; } }
// 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 InternalBrowseHitCollector(BoboBrowser boboBrowser, SortField[] sort, int offset, int count, bool fetchStoredFields) { this.boboBrowser = boboBrowser; reader = boboBrowser.GetIndexReader(); sortFields = QueryUtils.convertSort(sort, reader); this.offset = offset; this.count = count; this.numHits = offset + count; hitQueue = new SortedHitQueue(this.boboBrowser, sortFields, offset + count); totalHits = 0; this.fetchStoredFields = fetchStoredFields; this.reverseMul = (from s in sortFields select s.Reverse ? -1 : 1).ToArray(); }
public MultiTopDocsSortedHitCollector(MultiBoboBrowser multiBrowser, SortField[] sort, int offset, int count, bool fetchStoredFields) { this.sort = sort; this.offset = offset; this.count = count; this.multiBrowser = multiBrowser; IBrowsable[] subBrowsers = this.multiBrowser.getSubBrowsers(); subCollectors = new TopDocsSortedHitCollector[subBrowsers.Length]; for (int i = 0; i < subBrowsers.Length; ++i) { subCollectors[i] = subBrowsers[i].GetSortedHitCollector(sort, 0, this.offset + this.count, fetchStoredFields); } starts = this.multiBrowser.getStarts(); totalCount = 0; }
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); }
private static DocComparatorSource GetNonFacetComparatorSource(SortField sf) { string fieldname = sf.Field; CultureInfo locale = sf.Locale; if (locale != null) { return new DocComparatorSource.StringLocaleComparatorSource(fieldname, locale); } int type = sf.Type; switch (type) { case SortField.INT: return new DocComparatorSource.IntDocComparatorSource(fieldname); case SortField.FLOAT: return new DocComparatorSource.FloatDocComparatorSource(fieldname); case SortField.LONG: return new DocComparatorSource.LongDocComparatorSource(fieldname); case SortField.DOUBLE: return new DocComparatorSource.LongDocComparatorSource(fieldname); case SortField.BYTE: return new DocComparatorSource.ByteDocComparatorSource(fieldname); case SortField.SHORT: return new DocComparatorSource.ShortDocComparatorSource(fieldname); case SortField.CUSTOM: throw new InvalidOperationException("lucene custom sort no longer supported: " + fieldname); case SortField.STRING: return new DocComparatorSource.StringOrdComparatorSource(fieldname); case SortField.STRING_VAL: return new DocComparatorSource.StringValComparatorSource(fieldname); default: throw new InvalidOperationException("Illegal sort type: " + type + ", for field: " + fieldname); } }
public NAppIndexReader(Configuration.ConfigManager config) { // TODO: Use Central place to retrieve default setting of Index Full Path indexFullPath = config.GetSetting(SettingKeys.Index_Directory, System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Index")); indexFullPath = System.IO.Path.GetFullPath(indexFullPath); directory = FSDirectory.Open(new System.IO.DirectoryInfo(indexFullPath)); analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29); var sortFields = new SortField[2]; sortFields[0] = new SortField(FieldKeys.LogName, SortField.STRING); sortFields[1] = new SortField(FieldKeys.LogID, SortField.LONG); logNameIDSort = new Sort(sortFields); textQueryFields = new string[]{ FieldKeys.Service, FieldKeys.Method, FieldKeys.Detail_Desc, FieldKeys.Detail_Parm, }; }
/// <summary> Creates a hit queue sorted by the given list of fields.</summary> /// <param name="reader"> Index to use. /// </param> /// <param name="fields">Field 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].GetLocale(), fields[i].GetFactory()); 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()); } } Initialize(size); }
public static SortField[] convertSort(SortField[] sortSpec, BoboIndexReader idxReader) { SortField[] retVal = DEFAULT_SORT; if (sortSpec != null && sortSpec.Length > 0) { List<SortField> sortList = new List<SortField>(sortSpec.Length + 1); bool relevanceSortAdded = false; for (int i = 0; i < sortSpec.Length; ++i) { if (SortField.FIELD_DOC.Equals(sortSpec[i])) { sortList.Add(SortField.FIELD_DOC); } else if (SortField.FIELD_SCORE.Equals(sortSpec[i])) { sortList.Add(SortField.FIELD_SCORE); relevanceSortAdded = true; } else { string fieldname = sortSpec[i].Field; if (fieldname != null) { SortField sf = sortSpec[i]; sortList.Add(sf); } } } if (!relevanceSortAdded) { sortList.Add(SortField.FIELD_SCORE); } retVal = sortList.ToArray(); } return retVal; }
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>Sets the sort to the given criteria. </summary> public virtual void SetSort(SortField field) { this.fields = new SortField[]{field}; }
/// <summary>Sorts by the criteria in the given SortField. </summary> public Sort(SortField field) { SetSort(field); }
/// <summary>Sorts in succession by the criteria in each SortField. </summary> public Sort(SortField[] fields) { SetSort(fields); }
public override void SetUp() { base.SetUp(); // LUCENENET specific: Moved this logic here to ensure that it is executed // after the class is setup - a field is way to early to execute this. bool supportsDocValues = Codec.Default.Name.Equals("Lucene3x", StringComparison.Ordinal) == false; AllSortFields = new List <SortField>(Arrays.AsList(new SortField[] { #pragma warning disable 612,618 new SortField("byte", SortFieldType.BYTE, false), new SortField("short", SortFieldType.INT16, false), #pragma warning restore 612,618 new SortField("int", SortFieldType.INT32, false), new SortField("long", SortFieldType.INT64, false), new SortField("float", SortFieldType.SINGLE, false), new SortField("double", SortFieldType.DOUBLE, false), new SortField("bytes", SortFieldType.STRING, false), new SortField("bytesval", SortFieldType.STRING_VAL, false), #pragma warning disable 612,618 new SortField("byte", SortFieldType.BYTE, true), new SortField("short", SortFieldType.INT16, true), #pragma warning restore 612,618 new SortField("int", SortFieldType.INT32, true), new SortField("long", SortFieldType.INT64, true), new SortField("float", SortFieldType.SINGLE, true), new SortField("double", SortFieldType.DOUBLE, true), new SortField("bytes", SortFieldType.STRING, true), new SortField("bytesval", SortFieldType.STRING_VAL, true), SortField.FIELD_SCORE, SortField.FIELD_DOC })); if (supportsDocValues) { AllSortFields.AddRange(Arrays.AsList(new SortField[] { new SortField("intdocvalues", SortFieldType.INT32, false), new SortField("floatdocvalues", SortFieldType.SINGLE, false), new SortField("sortedbytesdocvalues", SortFieldType.STRING, false), new SortField("sortedbytesdocvaluesval", SortFieldType.STRING_VAL, false), new SortField("straightbytesdocvalues", SortFieldType.STRING_VAL, false), new SortField("intdocvalues", SortFieldType.INT32, true), new SortField("floatdocvalues", SortFieldType.SINGLE, true), new SortField("sortedbytesdocvalues", SortFieldType.STRING, true), new SortField("sortedbytesdocvaluesval", SortFieldType.STRING_VAL, true), new SortField("straightbytesdocvalues", SortFieldType.STRING_VAL, true) })); } // Also test missing first / last for the "string" sorts: foreach (string field in new string[] { "bytes", "sortedbytesdocvalues" }) { for (int rev = 0; rev < 2; rev++) { bool reversed = rev == 0; SortField sf = new SortField(field, SortFieldType.STRING, reversed); sf.MissingValue = SortField.STRING_FIRST; AllSortFields.Add(sf); sf = new SortField(field, SortFieldType.STRING, reversed); sf.MissingValue = SortField.STRING_LAST; AllSortFields.Add(sf); } } int limit = AllSortFields.Count; for (int i = 0; i < limit; i++) { SortField sf = AllSortFields[i]; if (sf.Type == SortFieldType.INT32) { SortField sf2 = new SortField(sf.Field, SortFieldType.INT32, sf.IsReverse); sf2.MissingValue = Random.Next(); AllSortFields.Add(sf2); } else if (sf.Type == SortFieldType.INT64) { SortField sf2 = new SortField(sf.Field, SortFieldType.INT64, sf.IsReverse); sf2.MissingValue = Random.NextInt64(); AllSortFields.Add(sf2); } else if (sf.Type == SortFieldType.SINGLE) { SortField sf2 = new SortField(sf.Field, SortFieldType.SINGLE, sf.IsReverse); sf2.MissingValue = (float)Random.NextDouble(); AllSortFields.Add(sf2); } else if (sf.Type == SortFieldType.DOUBLE) { SortField sf2 = new SortField(sf.Field, SortFieldType.DOUBLE, sf.IsReverse); sf2.MissingValue = Random.NextDouble(); AllSortFields.Add(sf2); } } Dir = NewDirectory(); RandomIndexWriter iw = new RandomIndexWriter(Random, Dir, Similarity, TimeZone); int numDocs = AtLeast(200); for (int i = 0; i < numDocs; i++) { IList <Field> fields = new List <Field>(); fields.Add(NewTextField("english", English.Int32ToEnglish(i), Field.Store.NO)); fields.Add(NewTextField("oddeven", (i % 2 == 0) ? "even" : "odd", Field.Store.NO)); fields.Add(NewStringField("byte", "" + ((sbyte)Random.Next()).ToString(CultureInfo.InvariantCulture), Field.Store.NO)); fields.Add(NewStringField("short", "" + ((short)Random.Next()).ToString(CultureInfo.InvariantCulture), Field.Store.NO)); fields.Add(new Int32Field("int", Random.Next(), Field.Store.NO)); fields.Add(new Int64Field("long", Random.NextInt64(), Field.Store.NO)); fields.Add(new SingleField("float", (float)Random.NextDouble(), Field.Store.NO)); fields.Add(new DoubleField("double", Random.NextDouble(), Field.Store.NO)); fields.Add(NewStringField("bytes", TestUtil.RandomRealisticUnicodeString(Random), Field.Store.NO)); fields.Add(NewStringField("bytesval", TestUtil.RandomRealisticUnicodeString(Random), Field.Store.NO)); fields.Add(new DoubleField("double", Random.NextDouble(), Field.Store.NO)); if (supportsDocValues) { fields.Add(new NumericDocValuesField("intdocvalues", Random.Next())); fields.Add(new SingleDocValuesField("floatdocvalues", (float)Random.NextDouble())); fields.Add(new SortedDocValuesField("sortedbytesdocvalues", new BytesRef(TestUtil.RandomRealisticUnicodeString(Random)))); fields.Add(new SortedDocValuesField("sortedbytesdocvaluesval", new BytesRef(TestUtil.RandomRealisticUnicodeString(Random)))); fields.Add(new BinaryDocValuesField("straightbytesdocvalues", new BytesRef(TestUtil.RandomRealisticUnicodeString(Random)))); } Document document = new Document(); document.Add(new StoredField("id", "" + i)); if (isVerbose) { Console.WriteLine(" add doc id=" + i); } foreach (Field field in fields) { // So we are sometimes missing that field: if (Random.Next(5) != 4) { document.Add(field); if (isVerbose) { Console.WriteLine(" " + field); } } } iw.AddDocument(document); if (Random.Next(50) == 17) { iw.Commit(); } } Reader = iw.GetReader(); iw.Dispose(); Searcher = NewSearcher(Reader); if (isVerbose) { Console.WriteLine(" searcher=" + Searcher); } }
internal virtual void TestSort(bool useFrom, bool VERBOSE) { IndexReader reader = null; Directory dir = null; if (!VERBOSE) { Console.WriteLine("Verbosity disabled. Enable manually if needed."); } int numDocs = VERBOSE ? AtLeast(50) : AtLeast(1000); //final int numDocs = AtLeast(50); string[] tokens = new string[] { "a", "b", "c", "d", "e" }; if (VERBOSE) { Console.WriteLine("TEST: make index"); } { dir = NewDirectory(); RandomIndexWriter w = new RandomIndexWriter( #if FEATURE_INSTANCE_TESTDATA_INITIALIZATION this, #endif Random, dir); // w.setDoRandomForceMerge(false); // w.w.getConfig().SetMaxBufferedDocs(AtLeast(100)); string[] content = new string[AtLeast(20)]; for (int contentIDX = 0; contentIDX < content.Length; contentIDX++) { StringBuilder sb = new StringBuilder(); int numTokens = TestUtil.NextInt32(Random, 1, 10); for (int tokenIDX = 0; tokenIDX < numTokens; tokenIDX++) { sb.Append(tokens[Random.Next(tokens.Length)]).Append(' '); } content[contentIDX] = sb.ToString(); } for (int docIDX = 0; docIDX < numDocs; docIDX++) { Document doc = new Document(); doc.Add(NewStringField("string", TestUtil.RandomRealisticUnicodeString(Random), Field.Store.NO)); doc.Add(NewTextField("text", content[Random.Next(content.Length)], Field.Store.NO)); doc.Add(new SingleField("float", (float)Random.NextDouble(), Field.Store.NO)); int intValue; if (Random.Next(100) == 17) { intValue = int.MinValue; } else if (Random.Next(100) == 17) { intValue = int.MaxValue; } else { intValue = Random.Next(); } doc.Add(new Int32Field("int", intValue, Field.Store.NO)); if (VERBOSE) { Console.WriteLine(" doc=" + doc); } w.AddDocument(doc); } reader = w.GetReader(); w.Dispose(); } // NOTE: sometimes reader has just one segment, which is // important to test IndexSearcher searcher = NewSearcher(reader); IndexReaderContext ctx = searcher.TopReaderContext; ShardSearcher[] subSearchers; int[] docStarts; if (ctx is AtomicReaderContext) { subSearchers = new ShardSearcher[1]; docStarts = new int[1]; subSearchers[0] = new ShardSearcher((AtomicReaderContext)ctx, ctx); docStarts[0] = 0; } else { CompositeReaderContext compCTX = (CompositeReaderContext)ctx; int size = compCTX.Leaves.Count; subSearchers = new ShardSearcher[size]; docStarts = new int[size]; int docBase = 0; for (int searcherIDX = 0; searcherIDX < subSearchers.Length; searcherIDX++) { AtomicReaderContext leave = compCTX.Leaves[searcherIDX]; subSearchers[searcherIDX] = new ShardSearcher(leave, compCTX); docStarts[searcherIDX] = docBase; docBase += leave.Reader.MaxDoc; } } IList <SortField> sortFields = new List <SortField>(); sortFields.Add(new SortField("string", SortFieldType.STRING, true)); sortFields.Add(new SortField("string", SortFieldType.STRING, false)); sortFields.Add(new SortField("int", SortFieldType.INT32, true)); sortFields.Add(new SortField("int", SortFieldType.INT32, false)); sortFields.Add(new SortField("float", SortFieldType.SINGLE, true)); sortFields.Add(new SortField("float", SortFieldType.SINGLE, false)); sortFields.Add(new SortField(null, SortFieldType.SCORE, true)); sortFields.Add(new SortField(null, SortFieldType.SCORE, false)); sortFields.Add(new SortField(null, SortFieldType.DOC, true)); sortFields.Add(new SortField(null, SortFieldType.DOC, false)); for (int iter = 0; iter < 1000 * RandomMultiplier; iter++) { // TODO: custom FieldComp... Query query = new TermQuery(new Term("text", tokens[Random.Next(tokens.Length)])); Sort sort; if (Random.Next(10) == 4) { // Sort by score sort = null; } else { SortField[] randomSortFields = new SortField[TestUtil.NextInt32(Random, 1, 3)]; for (int sortIDX = 0; sortIDX < randomSortFields.Length; sortIDX++) { randomSortFields[sortIDX] = sortFields[Random.Next(sortFields.Count)]; } sort = new Sort(randomSortFields); } int numHits = TestUtil.NextInt32(Random, 1, numDocs + 5); //final int numHits = 5; if (VERBOSE) { Console.WriteLine("TEST: search query=" + query + " sort=" + sort + " numHits=" + numHits); } int from = -1; int size = -1; // First search on whole index: TopDocs topHits; if (sort == null) { if (useFrom) { TopScoreDocCollector c = TopScoreDocCollector.Create(numHits, Random.NextBoolean()); searcher.Search(query, c); from = TestUtil.NextInt32(Random, 0, numHits - 1); size = numHits - from; TopDocs tempTopHits = c.GetTopDocs(); if (from < tempTopHits.ScoreDocs.Length) { // Can't use TopDocs#topDocs(start, howMany), since it has different behaviour when start >= hitCount // than TopDocs#merge currently has ScoreDoc[] newScoreDocs = new ScoreDoc[Math.Min(size, tempTopHits.ScoreDocs.Length - from)]; Array.Copy(tempTopHits.ScoreDocs, from, newScoreDocs, 0, newScoreDocs.Length); tempTopHits.ScoreDocs = newScoreDocs; topHits = tempTopHits; } else { topHits = new TopDocs(tempTopHits.TotalHits, new ScoreDoc[0], tempTopHits.MaxScore); } } else { topHits = searcher.Search(query, numHits); } } else { TopFieldCollector c = TopFieldCollector.Create(sort, numHits, true, true, true, Random.NextBoolean()); searcher.Search(query, c); if (useFrom) { from = TestUtil.NextInt32(Random, 0, numHits - 1); size = numHits - from; TopDocs tempTopHits = c.GetTopDocs(); if (from < tempTopHits.ScoreDocs.Length) { // Can't use TopDocs#topDocs(start, howMany), since it has different behaviour when start >= hitCount // than TopDocs#merge currently has ScoreDoc[] newScoreDocs = new ScoreDoc[Math.Min(size, tempTopHits.ScoreDocs.Length - from)]; Array.Copy(tempTopHits.ScoreDocs, from, newScoreDocs, 0, newScoreDocs.Length); tempTopHits.ScoreDocs = newScoreDocs; topHits = tempTopHits; } else { topHits = new TopDocs(tempTopHits.TotalHits, new ScoreDoc[0], tempTopHits.MaxScore); } } else { topHits = c.GetTopDocs(0, numHits); } } if (VERBOSE) { if (useFrom) { Console.WriteLine("from=" + from + " size=" + size); } Console.WriteLine(" top search: " + topHits.TotalHits + " totalHits; hits=" + (topHits.ScoreDocs == null ? "null" : topHits.ScoreDocs.Length + " maxScore=" + topHits.MaxScore)); if (topHits.ScoreDocs != null) { for (int hitIDX = 0; hitIDX < topHits.ScoreDocs.Length; hitIDX++) { ScoreDoc sd = topHits.ScoreDocs[hitIDX]; Console.WriteLine(" doc=" + sd.Doc + " score=" + sd.Score); } } } // ... then all shards: Weight w = searcher.CreateNormalizedWeight(query); TopDocs[] shardHits = new TopDocs[subSearchers.Length]; for (int shardIDX = 0; shardIDX < subSearchers.Length; shardIDX++) { TopDocs subHits; ShardSearcher subSearcher = subSearchers[shardIDX]; if (sort == null) { subHits = subSearcher.Search(w, numHits); } else { TopFieldCollector c = TopFieldCollector.Create(sort, numHits, true, true, true, Random.NextBoolean()); subSearcher.Search(w, c); subHits = c.GetTopDocs(0, numHits); } shardHits[shardIDX] = subHits; if (VERBOSE) { Console.WriteLine(" shard=" + shardIDX + " " + subHits.TotalHits + " totalHits hits=" + (subHits.ScoreDocs == null ? "null" : subHits.ScoreDocs.Length.ToString())); if (subHits.ScoreDocs != null) { foreach (ScoreDoc sd in subHits.ScoreDocs) { Console.WriteLine(" doc=" + sd.Doc + " score=" + sd.Score); } } } } // Merge: TopDocs mergedHits; if (useFrom) { mergedHits = TopDocs.Merge(sort, from, size, shardHits); } else { mergedHits = TopDocs.Merge(sort, numHits, shardHits); } if (mergedHits.ScoreDocs != null) { // Make sure the returned shards are correct: for (int hitIDX = 0; hitIDX < mergedHits.ScoreDocs.Length; hitIDX++) { ScoreDoc sd = mergedHits.ScoreDocs[hitIDX]; Assert.AreEqual(ReaderUtil.SubIndex(sd.Doc, docStarts), sd.ShardIndex, "doc=" + sd.Doc + " wrong shard"); } } TestUtil.AssertEquals(topHits, mergedHits); } reader.Dispose(); dir.Dispose(); }
/// <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 terms in <code>field</code> possibly in reverse, /// then by index order (document number). /// </summary> public virtual void SetSort(System.String field, bool reverse) { SortField[] nfields = new SortField[] { new SortField(field, SortField.AUTO, reverse), SortField.FIELD_DOC }; fields = nfields; }
private long GetLongFromField(Document doc, SortField sortField) { var field = doc.GetField(sortField.Field); if (field == null) return 0; long data; if (long.TryParse(field.StringValue, out data) && data >= 0) return data; return 0; }
public override void SetUp() { base.SetUp(); AllSortFields = new List <SortField>(Arrays.AsList(new SortField[] { new SortField("byte", SortField.Type_e.BYTE, false), new SortField("short", SortField.Type_e.SHORT, false), new SortField("int", SortField.Type_e.INT, false), new SortField("long", SortField.Type_e.LONG, false), new SortField("float", SortField.Type_e.FLOAT, false), new SortField("double", SortField.Type_e.DOUBLE, false), new SortField("bytes", SortField.Type_e.STRING, false), new SortField("bytesval", SortField.Type_e.STRING_VAL, false), new SortField("byte", SortField.Type_e.BYTE, true), new SortField("short", SortField.Type_e.SHORT, true), new SortField("int", SortField.Type_e.INT, true), new SortField("long", SortField.Type_e.LONG, true), new SortField("float", SortField.Type_e.FLOAT, true), new SortField("double", SortField.Type_e.DOUBLE, true), new SortField("bytes", SortField.Type_e.STRING, true), new SortField("bytesval", SortField.Type_e.STRING_VAL, true), SortField.FIELD_SCORE, SortField.FIELD_DOC })); if (SupportsDocValues) { AllSortFields.AddRange(Arrays.AsList(new SortField[] { new SortField("intdocvalues", SortField.Type_e.INT, false), new SortField("floatdocvalues", SortField.Type_e.FLOAT, false), new SortField("sortedbytesdocvalues", SortField.Type_e.STRING, false), new SortField("sortedbytesdocvaluesval", SortField.Type_e.STRING_VAL, false), new SortField("straightbytesdocvalues", SortField.Type_e.STRING_VAL, false), new SortField("intdocvalues", SortField.Type_e.INT, true), new SortField("floatdocvalues", SortField.Type_e.FLOAT, true), new SortField("sortedbytesdocvalues", SortField.Type_e.STRING, true), new SortField("sortedbytesdocvaluesval", SortField.Type_e.STRING_VAL, true), new SortField("straightbytesdocvalues", SortField.Type_e.STRING_VAL, true) })); } // Also test missing first / last for the "string" sorts: foreach (string field in new string[] { "bytes", "sortedbytesdocvalues" }) { for (int rev = 0; rev < 2; rev++) { bool reversed = rev == 0; SortField sf = new SortField(field, SortField.Type_e.STRING, reversed); sf.MissingValue = SortField.STRING_FIRST; AllSortFields.Add(sf); sf = new SortField(field, SortField.Type_e.STRING, reversed); sf.MissingValue = SortField.STRING_LAST; AllSortFields.Add(sf); } } int limit = AllSortFields.Count; for (int i = 0; i < limit; i++) { SortField sf = AllSortFields[i]; if (sf.Type == SortField.Type_e.INT) { SortField sf2 = new SortField(sf.Field, SortField.Type_e.INT, sf.Reverse); sf2.MissingValue = Random().Next(); AllSortFields.Add(sf2); } else if (sf.Type == SortField.Type_e.LONG) { SortField sf2 = new SortField(sf.Field, SortField.Type_e.LONG, sf.Reverse); sf2.MissingValue = Random().NextLong(); AllSortFields.Add(sf2); } else if (sf.Type == SortField.Type_e.FLOAT) { SortField sf2 = new SortField(sf.Field, SortField.Type_e.FLOAT, sf.Reverse); sf2.MissingValue = (float)Random().NextDouble(); AllSortFields.Add(sf2); } else if (sf.Type == SortField.Type_e.DOUBLE) { SortField sf2 = new SortField(sf.Field, SortField.Type_e.DOUBLE, sf.Reverse); sf2.MissingValue = Random().NextDouble(); AllSortFields.Add(sf2); } } Dir = NewDirectory(); RandomIndexWriter iw = new RandomIndexWriter(Random(), Dir, Similarity, TimeZone); int numDocs = AtLeast(200); for (int i = 0; i < numDocs; i++) { IList <Field> fields = new List <Field>(); fields.Add(NewTextField("english", English.IntToEnglish(i), Field.Store.NO)); fields.Add(NewTextField("oddeven", (i % 2 == 0) ? "even" : "odd", Field.Store.NO)); fields.Add(NewStringField("byte", "" + ((sbyte)Random().Next()), Field.Store.NO)); fields.Add(NewStringField("short", "" + ((short)Random().Next()), Field.Store.NO)); fields.Add(new IntField("int", Random().Next(), Field.Store.NO)); fields.Add(new LongField("long", Random().NextLong(), Field.Store.NO)); fields.Add(new FloatField("float", (float)Random().NextDouble(), Field.Store.NO)); fields.Add(new DoubleField("double", Random().NextDouble(), Field.Store.NO)); fields.Add(NewStringField("bytes", TestUtil.RandomRealisticUnicodeString(Random()), Field.Store.NO)); fields.Add(NewStringField("bytesval", TestUtil.RandomRealisticUnicodeString(Random()), Field.Store.NO)); fields.Add(new DoubleField("double", Random().NextDouble(), Field.Store.NO)); if (SupportsDocValues) { fields.Add(new NumericDocValuesField("intdocvalues", Random().Next())); fields.Add(new FloatDocValuesField("floatdocvalues", (float)Random().NextDouble())); fields.Add(new SortedDocValuesField("sortedbytesdocvalues", new BytesRef(TestUtil.RandomRealisticUnicodeString(Random())))); fields.Add(new SortedDocValuesField("sortedbytesdocvaluesval", new BytesRef(TestUtil.RandomRealisticUnicodeString(Random())))); fields.Add(new BinaryDocValuesField("straightbytesdocvalues", new BytesRef(TestUtil.RandomRealisticUnicodeString(Random())))); } Document document = new Document(); document.Add(new StoredField("id", "" + i)); if (VERBOSE) { Console.WriteLine(" add doc id=" + i); } foreach (Field field in fields) { // So we are sometimes missing that field: if (Random().Next(5) != 4) { document.Add(field); if (VERBOSE) { Console.WriteLine(" " + field); } } } iw.AddDocument(document); if (Random().Next(50) == 17) { iw.Commit(); } } Reader = iw.Reader; iw.Dispose(); Searcher = NewSearcher(Reader); if (VERBOSE) { Console.WriteLine(" searcher=" + Searcher); } }
public virtual void TestRandomStringSort() { Random random = new J2N.Randomizer(Random.NextInt64()); int NUM_DOCS = AtLeast(100); Directory dir = NewDirectory(); RandomIndexWriter writer = new RandomIndexWriter(random, dir); bool allowDups = random.NextBoolean(); ISet <string> seen = new JCG.HashSet <string>(); int maxLength = TestUtil.NextInt32(random, 5, 100); if (Verbose) { Console.WriteLine("TEST: NUM_DOCS=" + NUM_DOCS + " maxLength=" + maxLength + " allowDups=" + allowDups); } int numDocs = 0; IList <BytesRef> docValues = new JCG.List <BytesRef>(); // TODO: deletions while (numDocs < NUM_DOCS) { Document doc = new Document(); // 10% of the time, the document is missing the value: BytesRef br; if (LuceneTestCase.Random.Next(10) != 7) { string s; if (random.NextBoolean()) { s = TestUtil.RandomSimpleString(random, maxLength); } else { s = TestUtil.RandomUnicodeString(random, maxLength); } if (!allowDups) { if (seen.Contains(s)) { continue; } seen.Add(s); } if (Verbose) { Console.WriteLine(" " + numDocs + ": s=" + s); } br = new BytesRef(s); if (DefaultCodecSupportsDocValues) { doc.Add(new SortedDocValuesField("stringdv", br)); doc.Add(new NumericDocValuesField("id", numDocs)); } else { doc.Add(NewStringField("id", Convert.ToString(numDocs), Field.Store.NO)); } doc.Add(NewStringField("string", s, Field.Store.NO)); docValues.Add(br); } else { br = null; if (Verbose) { Console.WriteLine(" " + numDocs + ": <missing>"); } docValues.Add(null); if (DefaultCodecSupportsDocValues) { doc.Add(new NumericDocValuesField("id", numDocs)); } else { doc.Add(NewStringField("id", Convert.ToString(numDocs), Field.Store.NO)); } } doc.Add(new StoredField("id", numDocs)); writer.AddDocument(doc); numDocs++; if (random.Next(40) == 17) { // force flush writer.GetReader().Dispose(); } } IndexReader r = writer.GetReader(); writer.Dispose(); if (Verbose) { Console.WriteLine(" reader=" + r); } IndexSearcher idxS = NewSearcher(r, false); int ITERS = AtLeast(100); for (int iter = 0; iter < ITERS; iter++) { bool reverse = random.NextBoolean(); TopFieldDocs hits; SortField sf; bool sortMissingLast; bool missingIsNull; if (DefaultCodecSupportsDocValues && random.NextBoolean()) { sf = new SortField("stringdv", SortFieldType.STRING, reverse); // Can only use sort missing if the DVFormat // supports docsWithField: sortMissingLast = DefaultCodecSupportsDocsWithField && Random.NextBoolean(); missingIsNull = DefaultCodecSupportsDocsWithField; } else { sf = new SortField("string", SortFieldType.STRING, reverse); sortMissingLast = Random.NextBoolean(); missingIsNull = true; } if (sortMissingLast) { sf.SetMissingValue(SortField.STRING_LAST); } Sort sort; if (random.NextBoolean()) { sort = new Sort(sf); } else { sort = new Sort(sf, SortField.FIELD_DOC); } int hitCount = TestUtil.NextInt32(random, 1, r.MaxDoc + 20); RandomFilter f = new RandomFilter(random, (float)random.NextDouble(), docValues); int queryType = random.Next(3); if (queryType == 0) { // force out of order BooleanQuery bq = new BooleanQuery(); // Add a Query with SHOULD, since bw.Scorer() returns BooleanScorer2 // which delegates to BS if there are no mandatory clauses. bq.Add(new MatchAllDocsQuery(), Occur.SHOULD); // Set minNrShouldMatch to 1 so that BQ will not optimize rewrite to return // the clause instead of BQ. bq.MinimumNumberShouldMatch = 1; hits = idxS.Search(bq, f, hitCount, sort, random.NextBoolean(), random.NextBoolean()); } else if (queryType == 1) { hits = idxS.Search(new ConstantScoreQuery(f), null, hitCount, sort, random.NextBoolean(), random.NextBoolean()); } else { hits = idxS.Search(new MatchAllDocsQuery(), f, hitCount, sort, random.NextBoolean(), random.NextBoolean()); } if (Verbose) { Console.WriteLine("\nTEST: iter=" + iter + " " + hits.TotalHits + " hits; topN=" + hitCount + "; reverse=" + reverse + "; sortMissingLast=" + sortMissingLast + " sort=" + sort); } // Compute expected results: var expected = f.matchValues.ToList(); expected.Sort(Comparer <BytesRef> .Create((a, b) => { if (a is null) { if (b is null) { return(0); } if (sortMissingLast) { return(1); } else { return(-1); } } else if (b is null) { if (sortMissingLast) { return(-1); } else { return(1); } } else { return(a.CompareTo(b)); } })); if (reverse) { expected.Reverse(); } if (Verbose) { Console.WriteLine(" expected:"); for (int idx = 0; idx < expected.Count; idx++) { BytesRef br = expected[idx]; if (br is null && missingIsNull == false) { br = new BytesRef(); } Console.WriteLine(" " + idx + ": " + (br is null ? "<missing>" : br.Utf8ToString())); if (idx == hitCount - 1) { break; } } } if (Verbose) { Console.WriteLine(" actual:"); for (int hitIDX = 0; hitIDX < hits.ScoreDocs.Length; hitIDX++) { FieldDoc fd = (FieldDoc)hits.ScoreDocs[hitIDX]; BytesRef br = (BytesRef)fd.Fields[0]; Console.WriteLine(" " + hitIDX + ": " + (br is null ? "<missing>" : br.Utf8ToString()) + " id=" + idxS.Doc(fd.Doc).Get("id")); } } for (int hitIDX = 0; hitIDX < hits.ScoreDocs.Length; hitIDX++) { FieldDoc fd = (FieldDoc)hits.ScoreDocs[hitIDX]; BytesRef br = expected[hitIDX]; if (br is null && missingIsNull == false) { br = new BytesRef(); } // Normally, the old codecs (that don't support // docsWithField via doc values) will always return // an empty BytesRef for the missing case; however, // if all docs in a given segment were missing, in // that case it will return null! So we must map // null here, too: BytesRef br2 = (BytesRef)fd.Fields[0]; if (br2 is null && missingIsNull == false) { br2 = new BytesRef(); } Assert.AreEqual(br, br2, "hit=" + hitIDX + " has wrong sort value"); } } r.Dispose(); dir.Dispose(); }
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>Sets the sort to the given criteria in succession. </summary> public virtual void SetSort(SortField[] fields) { this.fields = fields; }
/// <summary> /// Sorts by the criteria in the given SortField. </summary> public Sort(SortField field) { SetSort(field); }
/// <summary>Sets the sort to the given criteria. </summary> public virtual void SetSort(SortField field) { this.fields = new ArraySegment <SortField>(new SortField[] { field }); }
public override BrowseHit[] GetTopDocs() { List<IEnumerable<BrowseHit>> iteratorList = new List<IEnumerable<BrowseHit>>(subCollectors.Length); for (int i = 0; i < subCollectors.Length; ++i) { int @base = starts[i]; try { BrowseHit[] subHits = subCollectors[i].GetTopDocs(); foreach (BrowseHit hit in subHits) { hit.DocId = hit.DocId + @base; } iteratorList.Add(subHits); } catch (System.IO.IOException ioe) { logger.Error(ioe.Message, ioe); } } SortField[] sf = sort; if (sf == null || sf.Length == 0) { sf = new SortField[] { SortField.FIELD_SCORE }; } IComparer<BrowseHit> comparator = new SortedFieldBrowseHitComparator(sf); List<BrowseHit> mergedList = ListMerger.MergeLists(offset, count, iteratorList.ToArray(), comparator); return mergedList.ToArray(); }
private static DocComparatorSource GetComparatorSource(IBrowsable browser, SortField sf) { DocComparatorSource compSource = null; if (SortField.FIELD_DOC.Equals(sf)) { compSource = new DocComparatorSource.DocIdDocComparatorSource(); } else if (SortField.FIELD_SCORE.Equals(sf) || sf.Type == SortField.SCORE) { // we want to do reverse sorting regardless for relevance compSource = new ReverseDocComparatorSource(new DocComparatorSource.RelevanceDocComparatorSource()); } else if (sf is BoboCustomSortField) { BoboCustomSortField custField = (BoboCustomSortField)sf; DocComparatorSource src = custField.GetCustomComparatorSource(); Debug.Assert(src != null); compSource = src; } else { IEnumerable<string> facetNames = browser.FacetNames; string sortName = sf.Field; if (facetNames.Contains(sortName)) { var handler = browser.GetFacetHandler(sortName); Debug.Assert(handler != null); compSource = handler.GetDocComparatorSource(); } else { // default lucene field logger.Info("doing default lucene sort for: " + sf); compSource = GetNonFacetComparatorSource(sf); } } bool reverse = sf.Reverse; if (reverse) { compSource = new ReverseDocComparatorSource(compSource); } compSource.IsReverse = reverse; return compSource; }
/// <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> 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); } }
private static SortField Convert(IBrowsable browser, SortField sort) { string field = sort.Field; var facetHandler = browser.GetFacetHandler(field); if (facetHandler != null) { //browser.GetFacetHandler(field); // BUG? this does nothing with the result. BoboCustomSortField sortField = new BoboCustomSortField(field, sort.Reverse, facetHandler.GetDocComparatorSource()); return sortField; } else { return sort; } }
private string GetStringFromField(Document doc, SortField sortField) { var field = doc.GetField(sortField.Field); return field == null ? "" : field.StringValue; }
public static SortCollector BuildSortCollector(IBrowsable browser, Query q, SortField[] sort, int offset, int count, bool forceScoring, bool fetchStoredFields, IEnumerable<string> termVectorsToFetch, string[] groupBy, int maxPerGroup, bool collectDocIdCache) { bool doScoring = forceScoring; if (sort == null || sort.Length == 0) { if (q != null && !(q is MatchAllDocsQuery)) { sort = new SortField[] { SortField.FIELD_SCORE }; } } if (sort == null || sort.Length == 0) { sort = new SortField[] { SortField.FIELD_DOC }; } IEnumerable<string> facetNames = browser.FacetNames; foreach (SortField sf in sort) { if (sf.Type == SortField.SCORE) { doScoring = true; break; } } DocComparatorSource compSource; if (sort.Length == 1) { SortField sf = Convert(browser, sort[0]); compSource = GetComparatorSource(browser, sf); } else { DocComparatorSource[] compSources = new DocComparatorSource[sort.Length]; for (int i = 0; i < sort.Length; ++i) { compSources[i] = GetComparatorSource(browser, Convert(browser, sort[i])); } compSource = new MultiDocIdComparatorSource(compSources); } return new SortCollectorImpl(compSource, sort, browser, offset, count, doScoring, fetchStoredFields, termVectorsToFetch, groupBy, maxPerGroup, collectDocIdCache); }
/// <summary> Just like <see cref="Search(Weight, Filter, int, Sort)" />, but you choose /// whether or not the fields in the returned <see cref="FieldDoc" /> instances /// should be set by specifying fillFields.<br/> /// /// <p/> /// NOTE: this does not compute scores by default. If you need scores, create /// a <see cref="TopFieldCollector" /> instance by calling /// <see cref="TopFieldCollector.create" /> and then pass that to /// <see cref="Search(Weight, Filter, Collector)" />. /// <p/> /// </summary> public virtual TopFieldDocs Search(Weight weight, Filter filter, int nDocs, Sort sort, bool fillFields) { nDocs = 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(); }
protected SortCollector(SortField[] sortFields, bool fetchStoredFields) { _sortFields = sortFields; _fetchStoredFields = fetchStoredFields; }