예제 #1
0
        /// <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;
		}
예제 #3
0
        /// <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);
        }