/// <summary> Given a FieldDoc object, stores the values used /// to sort the given document. These values are not the raw /// values out of the index, but the internal representation /// of them. This is so the given search hit can be collated /// by a MultiSearcher with other search hits. /// </summary> /// <param name="doc"> The FieldDoc to store sort values into. /// </param> /// <returns> The same FieldDoc passed in. /// </returns> /// <seealso cref="Searchable#Search(Query,Filter,int,Sort)"> /// </seealso> internal virtual FieldDoc FillFields(FieldDoc doc) { int n = comparators.Length; System.IComparable[] fields = new System.IComparable[n]; for (int i = 0; i < n; ++i) { fields[i] = comparators[i].SortValue(doc); } doc.fields = fields; if (maxscore > 1.0f) { doc.score /= maxscore; // normalize scores } return(doc); }
/// <summary> Given a FieldDoc object, stores the values used /// to sort the given document. These values are not the raw /// values out of the index, but the internal representation /// of them. This is so the given search hit can be collated /// by a MultiSearcher with other search hits. /// </summary> /// <param name="doc"> The FieldDoc to store sort values into. /// </param> /// <returns> The same FieldDoc passed in. /// </returns> /// <seealso cref="Searchable#Search(Query,Filter,int,Sort)"> /// </seealso> internal virtual FieldDoc FillFields(FieldDoc doc) { int n = comparators.Length; System.IComparable[] fields = new System.IComparable[n]; for (int i = 0; i < n; ++i) fields[i] = comparators[i].SortValue(doc); doc.fields = fields; if (maxscore > 1.0f) doc.score /= maxscore; // normalize scores return doc; }
/// <summary> Returns whether <code>a</code> is less relevant than <code>b</code>.</summary> /// <param name="a">ScoreDoc /// </param> /// <param name="b">ScoreDoc /// </param> /// <returns> <code>true</code> if document <code>a</code> should be sorted after document <code>b</code>. /// </returns> public override bool LessThan(System.Object a, System.Object b) { FieldDoc docA = (FieldDoc)a; FieldDoc docB = (FieldDoc)b; int n = fields.Length; int c = 0; for (int i = 0; i < n && c == 0; ++i) { int type = fields[i].GetType(); if (fields[i].GetReverse()) { switch (type) { case SortField.SCORE: float r1 = (float)((System.Single)docA.fields[i]); float r2 = (float)((System.Single)docB.fields[i]); if (r1 < r2) { c = -1; } if (r1 > r2) { c = 1; } break; case SortField.DOC: case SortField.INT: int i1 = ((System.Int32)docA.fields[i]); int i2 = ((System.Int32)docB.fields[i]); if (i1 > i2) { c = -1; } if (i1 < i2) { c = 1; } break; case SortField.STRING: System.String s1 = (System.String)docA.fields[i]; System.String s2 = (System.String)docB.fields[i]; if (s2 == null) { c = -1; } // could be null if there are else if (s1 == null) { c = 1; } // no terms in the given Field else if (fields[i].GetLocale() == null) { c = String.CompareOrdinal(s2, s1); } else { c = collators[i].Compare(s2.ToString(), s1.ToString()); } break; case SortField.FLOAT: float f1 = (float)((System.Single)docA.fields[i]); float f2 = (float)((System.Single)docB.fields[i]); if (f1 > f2) { c = -1; } if (f1 < f2) { c = 1; } break; case SortField.CUSTOM: c = docB.fields[i].CompareTo(docA.fields[i]); break; case SortField.AUTO: // we cannot handle this - even if we determine the type of object (Float or // Integer), we don't necessarily know how to compare them (both SCORE and // FLOAT both contain floats, but are sorted opposite of each other). Before // we get here, each AUTO should have been replaced with its actual value. throw new System.SystemException("FieldDocSortedHitQueue cannot use an AUTO SortField"); default: throw new System.SystemException("invalid SortField type: " + type); } } else { switch (type) { case SortField.SCORE: float r1 = (float)((System.Single)docA.fields[i]); float r2 = (float)((System.Single)docB.fields[i]); if (r1 > r2) { c = -1; } if (r1 < r2) { c = 1; } break; case SortField.DOC: case SortField.INT: int i1 = ((System.Int32)docA.fields[i]); int i2 = ((System.Int32)docB.fields[i]); if (i1 < i2) { c = -1; } if (i1 > i2) { c = 1; } break; case SortField.STRING: System.String s1 = (System.String)docA.fields[i]; System.String s2 = (System.String)docB.fields[i]; // null values need to be sorted first, because of how FieldCache.getStringIndex() // works - in that routine, any documents without a value in the given Field are // put first. if (s1 == null) { c = -1; } // could be null if there are else if (s2 == null) { c = 1; } // no terms in the given Field else if (fields[i].GetLocale() == null) { c = String.CompareOrdinal(s1, s2); } else { c = collators[i].Compare(s1.ToString(), s2.ToString()); } break; case SortField.FLOAT: float f1 = (float)((System.Single)docA.fields[i]); float f2 = (float)((System.Single)docB.fields[i]); if (f1 < f2) { c = -1; } if (f1 > f2) { c = 1; } break; case SortField.CUSTOM: c = docA.fields[i].CompareTo(docB.fields[i]); break; case SortField.AUTO: // we cannot handle this - even if we determine the type of object (Float or // Integer), we don't necessarily know how to compare them (both SCORE and // FLOAT both contain floats, but are sorted opposite of each other). Before // we get here, each AUTO should have been replaced with its actual value. throw new System.SystemException("FieldDocSortedHitQueue cannot use an AUTO SortField"); default: throw new System.SystemException("invalid SortField type: " + type); } } } return(c > 0); }