/* * Copyright 2005 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; namespace Lucene.Net.Search { /// A Scorer for queries with a required part and an optional part. /// Delays SkipTo() on the optional part until a score() is needed. ///
/// This Scorer implements {@link Scorer#SkipTo(int)}. ///
public class ReqOptSumScorer : Scorer { /// The scorers passed from the constructor. /// These are set to null as soon as their Next() or SkipTo() returns false. /// private Scorer reqScorer; private Scorer optScorer; /// Construct a ReqOptScorer. /// The required scorer. This must match. /// /// The optional scorer. This is used for scoring only. /// public ReqOptSumScorer(Scorer reqScorer, Scorer optScorer) : base(null) { // No similarity used. this.reqScorer = reqScorer; this.optScorer = optScorer; } private bool firstTimeOptScorer = true; public override bool Next() { return reqScorer.Next(); } public override bool SkipTo(int target) { return reqScorer.SkipTo(target); } public override int Doc() { return reqScorer.Doc(); } /// Returns the score of the current document matching the query. /// Initially invalid, until {@link #Next()} is called the first time. /// /// The score of the required scorer, eventually increased by the score /// of the optional scorer when it also matches the current document. /// public override float Score() { int curDoc = reqScorer.Doc(); float reqScore = reqScorer.Score(); if (firstTimeOptScorer) { firstTimeOptScorer = false; if (!optScorer.SkipTo(curDoc)) { optScorer = null; return reqScore; } } else if (optScorer == null) { return reqScore; } else if ((optScorer.Doc() < curDoc) && (!optScorer.SkipTo(curDoc))) { optScorer = null; return reqScore; } // assert (optScorer != null) && (optScorer.doc() >= curDoc); return (optScorer.Doc() == curDoc)?reqScore + optScorer.Score():reqScore; } /// Explain the score of a document. /// Also show the total score. /// See BooleanScorer.explain() on how to do this. /// public override Explanation Explain(int doc) { Explanation res = new Explanation(); res.SetDescription("required, optional"); res.AddDetail(reqScorer.Explain(doc)); res.AddDetail(optScorer.Explain(doc)); return res; } } }