Ejemplo n.º 1
0
        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));
        }
Ejemplo n.º 2
0
        override public void  Run()
        {
            try
            {
                docs = (sort == null)?searchable.Search(weight, filter, nDocs):searchable.Search(weight, filter, nDocs, sort);
            }
            // Store the IOException for later use by the caller of this thread
            catch (System.Exception e)
            {
                this.ioe = e;
            }
            if (this.ioe == null)
            {
                // if we are sorting by fields, we need to tell the field sorted hit queue
                // the actual type of fields, in case the original list contained AUTO.
                // if the searchable returns null for fields, we'll have problems.
                if (sort != null)
                {
                    TopFieldDocs docsFields = (TopFieldDocs)docs;
                    // 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 searchables.
                    for (int j = 0; j < docsFields.fields.Length; j++)
                    {
                        if (docsFields.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;
                        }
                    }

                    ((FieldDocSortedHitQueue)hq).SetFields(docsFields.fields);
                }
                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
                    //it would be so nice if we had a thread-safe insert
                    lock (hq)
                    {
                        if (!hq.Insert(scoreDoc))
                        {
                            break;
                        }
                    }                     // no more scores > minScore
                }
            }
        }
Ejemplo n.º 3
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(Weight,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);
        }
Ejemplo n.º 4
0
        /*
         * Only the following callback methods need to be overridden since
         * topDocs(int, int) calls them to return the results.
         */

        protected internal override void  PopulateResults(ScoreDoc[] results, int howMany)
        {
            if (fillFields)
            {
                // avoid casting if unnecessary.
                FieldValueHitQueue queue = (FieldValueHitQueue)pq;
                for (int i = howMany - 1; i >= 0; i--)
                {
                    results[i] = queue.FillFields((Entry)queue.Pop());
                }
            }
            else
            {
                for (int i = howMany - 1; i >= 0; i--)
                {
                    Entry entry = (Entry)pq.Pop();
                    results[i] = new FieldDoc(entry.docID, entry.score);
                }
            }
        }
Ejemplo n.º 5
0
		// javadoc inherited
		public override void  Collect(int doc, float score)
		{
			if (score > 0.0f)
			{
				totalHits++;
				if (reusableFD == null)
					reusableFD = new FieldDoc(doc, score);
				else
				{
					// Whereas TopScoreDocCollector can skip this if the
					// score is not competitive, we cannot because the
					// comparators in the FieldSortedHitQueue.lessThan
					// aren't in general congruent with "higher score
					// wins"
					reusableFD.score = score;
					reusableFD.doc = doc;
				}
				reusableFD = (FieldDoc) hq.InsertWithOverflow(reusableFD);
			}
		}
Ejemplo n.º 6
0
 // javadoc inherited
 public override void  Collect(int doc, float score)
 {
     if (score > 0.0f)
     {
         totalHits++;
         if (reusableFD == null)
         {
             reusableFD = new FieldDoc(doc, score);
         }
         else
         {
             // Whereas TopScoreDocCollector can skip this if the
             // score is not competitive, we cannot because the
             // comparators in the FieldSortedHitQueue.lessThan
             // aren't in general congruent with "higher score
             // wins"
             reusableFD.score = score;
             reusableFD.doc   = doc;
         }
         reusableFD = (FieldDoc)hq.InsertWithOverflow(reusableFD);
     }
 }
Ejemplo n.º 7
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(Weight,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;
		}
Ejemplo n.º 8
0
		// The signature of this method takes a FieldDoc in order to avoid
		// the unneeded cast to retrieve the score.
		// inherit javadoc
		public virtual bool Insert(FieldDoc fdoc)
		{
			UpdateMaxScore(fdoc);
			return base.Insert(fdoc);
		}
Ejemplo n.º 9
0
		// Update maxscore.
		private void  UpdateMaxScore(FieldDoc fdoc)
		{
			maxscore = System.Math.Max(maxscore, fdoc.score);
		}
Ejemplo n.º 10
0
		/*
		* Only the following callback methods need to be overridden since
		* topDocs(int, int) calls them to return the results.
		*/
		
		protected internal override void  PopulateResults(ScoreDoc[] results, int howMany)
		{
			if (fillFields)
			{
				// avoid casting if unnecessary.
				FieldValueHitQueue queue = (FieldValueHitQueue) pq;
				for (int i = howMany - 1; i >= 0; i--)
				{
					results[i] = queue.FillFields((Entry) queue.Pop());
				}
			}
			else
			{
				for (int i = howMany - 1; i >= 0; i--)
				{
					Entry entry = (Entry) pq.Pop();
					results[i] = new FieldDoc(entry.docID, entry.score);
				}
			}
		}
Ejemplo n.º 11
0
 // The signature of this method takes a FieldDoc in order to avoid
 // the unneeded cast to retrieve the score.
 // inherit javadoc
 public virtual bool Insert(FieldDoc fdoc)
 {
     UpdateMaxScore(fdoc);
     return(base.Insert(fdoc));
 }
Ejemplo n.º 12
0
 // Update maxscore.
 private void  UpdateMaxScore(FieldDoc fdoc)
 {
     maxscore = System.Math.Max(maxscore, fdoc.score);
 }
Ejemplo n.º 13
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();
                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.LONG:  {
                    long l1 = (long)((System.Int64)docA.fields[i]);
                    long l2 = (long)((System.Int64)docB.fields[i]);
                    if (l1 < l2)
                    {
                        c = -1;
                    }
                    if (l1 > l2)
                    {
                        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 both are null, the next SortField is used
                    if (s1 == null)
                    {
                        c = (s2 == null)?0:-1;
                    }
                    else if (s2 == null)
                    {
                        c = 1;
                    }
                    //
                    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.DOUBLE:  {
                    double d1 = ((System.Double)docA.fields[i]);
                    double d2 = ((System.Double)docB.fields[i]);
                    if (d1 < d2)
                    {
                        c = -1;
                    }
                    if (d1 > d2)
                    {
                        c = 1;
                    }
                    break;
                }

                case SortField.BYTE:  {
                    int i1 = (sbyte)((System.SByte)docA.fields[i]);
                    int i2 = (sbyte)((System.SByte)docB.fields[i]);
                    if (i1 < i2)
                    {
                        c = -1;
                    }
                    if (i1 > i2)
                    {
                        c = 1;
                    }
                    break;
                }

                case SortField.SHORT:  {
                    int i1 = (short)((System.Int16)docA.fields[i]);
                    int i2 = (short)((System.Int16)docB.fields[i]);
                    if (i1 < i2)
                    {
                        c = -1;
                    }
                    if (i1 > i2)
                    {
                        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 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);
                }
                }
                if (fields[i].GetReverse())
                {
                    c = -c;
                }
            }

            // avoid random sort order that could lead to duplicates (bug #31241):
            if (c == 0)
            {
                return(docA.doc > docB.doc);
            }

            return(c > 0);
        }