BooleanScorer2.cs
上传用户:zhangkuixh
上传日期:2013-09-30
资源大小:5473k
文件大小:15k
- /*
- * 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
- {
-
- /// <summary>An alternative to BooleanScorer.
- /// <br>Uses ConjunctionScorer, DisjunctionScorer, ReqOptScorer and ReqExclScorer.
- /// <br>Implements skipTo(), and has no limitations on the numbers of added scorers.
- /// </summary>
- class BooleanScorer2 : Scorer
- {
- private class AnonymousClassDisjunctionSumScorer : DisjunctionSumScorer
- {
- private void InitBlock(BooleanScorer2 enclosingInstance)
- {
- this.enclosingInstance = enclosingInstance;
- }
- private BooleanScorer2 enclosingInstance;
- public BooleanScorer2 Enclosing_Instance
- {
- get
- {
- return enclosingInstance;
- }
-
- }
- internal AnonymousClassDisjunctionSumScorer(BooleanScorer2 enclosingInstance, System.Collections.IList Param1, int Param2):base(Param1, Param2)
- {
- InitBlock(enclosingInstance);
- }
- private int lastScoredDoc = - 1;
- public override float Score()
- {
- if (Doc() > lastScoredDoc)
- {
- lastScoredDoc = Doc();
- Enclosing_Instance.coordinator.nrMatchers += base.nrMatchers;
- }
- return base.Score();
- }
- }
- private class AnonymousClassConjunctionScorer : ConjunctionScorer
- {
- private void InitBlock(int requiredNrMatchers, BooleanScorer2 enclosingInstance)
- {
- this.requiredNrMatchers = requiredNrMatchers;
- this.enclosingInstance = enclosingInstance;
- }
- private int requiredNrMatchers;
- private BooleanScorer2 enclosingInstance;
- public BooleanScorer2 Enclosing_Instance
- {
- get
- {
- return enclosingInstance;
- }
-
- }
- internal AnonymousClassConjunctionScorer(int requiredNrMatchers, BooleanScorer2 enclosingInstance, Lucene.Net.Search.Similarity Param1):base(Param1)
- {
- InitBlock(requiredNrMatchers, enclosingInstance);
- }
- private int lastScoredDoc = - 1;
-
- public override float Score()
- {
- if (Doc() > lastScoredDoc)
- {
- lastScoredDoc = Doc();
- Enclosing_Instance.coordinator.nrMatchers += requiredNrMatchers;
- }
- // All scorers match, so defaultSimilarity super.score() always has 1 as
- // the coordination factor.
- // Therefore the sum of the scores of the requiredScorers
- // is used as score.
- return base.Score();
- }
- }
- private System.Collections.ArrayList requiredScorers = new System.Collections.ArrayList();
- private System.Collections.ArrayList optionalScorers = new System.Collections.ArrayList();
- private System.Collections.ArrayList prohibitedScorers = new System.Collections.ArrayList();
-
-
- private class Coordinator
- {
- public Coordinator(BooleanScorer2 enclosingInstance)
- {
- InitBlock(enclosingInstance);
- }
- private void InitBlock(BooleanScorer2 enclosingInstance)
- {
- this.enclosingInstance = enclosingInstance;
- }
- private BooleanScorer2 enclosingInstance;
- public BooleanScorer2 Enclosing_Instance
- {
- get
- {
- return enclosingInstance;
- }
-
- }
- internal int maxCoord = 0; // to be increased for each non prohibited scorer
-
- private float[] coordFactors = null;
-
- internal virtual void Init()
- {
- // use after all scorers have been added.
- coordFactors = new float[maxCoord + 1];
- Similarity sim = Enclosing_Instance.GetSimilarity();
- for (int i = 0; i <= maxCoord; i++)
- {
- coordFactors[i] = sim.Coord(i, maxCoord);
- }
- }
-
- internal int nrMatchers; // to be increased by score() of match counting scorers.
-
- internal virtual void InitDoc()
- {
- nrMatchers = 0;
- }
-
- internal virtual float CoordFactor()
- {
- return coordFactors[nrMatchers];
- }
- }
-
- private Coordinator coordinator;
-
- /// <summary>The scorer to which all scoring will be delegated,
- /// except for computing and using the coordination factor.
- /// </summary>
- private Scorer countingSumScorer = null;
-
- /// <summary>The number of optionalScorers that need to match (if there are any) </summary>
- private int minNrShouldMatch;
-
- /// <summary>Create a BooleanScorer2.</summary>
- /// <param name="similarity">The similarity to be used.
- /// </param>
- /// <param name="minNrShouldMatch">The minimum number of optional added scorers
- /// that should match during the search.
- /// In case no required scorers are added,
- /// at least one of the optional scorers will have to
- /// match during the search.
- /// </param>
- public BooleanScorer2(Similarity similarity, int minNrShouldMatch):base(similarity)
- {
- if (minNrShouldMatch < 0)
- {
- throw new System.ArgumentException("Minimum number of optional scorers should not be negative");
- }
- coordinator = new Coordinator(this);
- this.minNrShouldMatch = minNrShouldMatch;
- }
-
- /// <summary>Create a BooleanScorer2.
- /// In no required scorers are added,
- /// at least one of the optional scorers will have to match during the search.
- /// </summary>
- /// <param name="similarity">The similarity to be used.
- /// </param>
- public BooleanScorer2(Similarity similarity) : this(similarity, 0)
- {
- }
-
- public virtual void Add(Scorer scorer, bool required, bool prohibited)
- {
- if (!prohibited)
- {
- coordinator.maxCoord++;
- }
-
- if (required)
- {
- if (prohibited)
- {
- throw new System.ArgumentException("scorer cannot be required and prohibited");
- }
- requiredScorers.Add(scorer);
- }
- else if (prohibited)
- {
- prohibitedScorers.Add(scorer);
- }
- else
- {
- optionalScorers.Add(scorer);
- }
- }
-
- /// <summary>Initialize the match counting scorer that sums all the
- /// scores. <p>
- /// When "counting" is used in a name it means counting the number
- /// of matching scorers.<br>
- /// When "sum" is used in a name it means score value summing
- /// over the matching scorers
- /// </summary>
- private void InitCountingSumScorer()
- {
- coordinator.Init();
- countingSumScorer = MakeCountingSumScorer();
- }
-
- /// <summary>Count a scorer as a single match. </summary>
- private class SingleMatchScorer : Scorer
- {
- private void InitBlock(BooleanScorer2 enclosingInstance)
- {
- this.enclosingInstance = enclosingInstance;
- }
- private BooleanScorer2 enclosingInstance;
- public BooleanScorer2 Enclosing_Instance
- {
- get
- {
- return enclosingInstance;
- }
-
- }
- private Scorer scorer;
- private int lastScoredDoc = - 1;
-
- internal SingleMatchScorer(BooleanScorer2 enclosingInstance, Scorer scorer) : base(scorer.GetSimilarity())
- {
- InitBlock(enclosingInstance);
- this.scorer = scorer;
- }
- public override float Score()
- {
- if (Doc() > lastScoredDoc)
- {
- lastScoredDoc = Doc();
- Enclosing_Instance.coordinator.nrMatchers++;
- }
- return scorer.Score();
- }
- public override int Doc()
- {
- return scorer.Doc();
- }
- public override bool Next()
- {
- return scorer.Next();
- }
- public override bool SkipTo(int docNr)
- {
- return scorer.SkipTo(docNr);
- }
- public override Explanation Explain(int docNr)
- {
- return scorer.Explain(docNr);
- }
- }
-
- private Scorer CountingDisjunctionSumScorer(System.Collections.IList scorers, int minMrShouldMatch)
- // each scorer from the list counted as a single matcher
- {
- return new AnonymousClassDisjunctionSumScorer(this, scorers, minMrShouldMatch);
- }
-
- private static Similarity defaultSimilarity = new DefaultSimilarity();
-
- private Scorer CountingConjunctionSumScorer(System.Collections.IList requiredScorers)
- {
- // each scorer from the list counted as a single matcher
- int requiredNrMatchers = requiredScorers.Count;
- ConjunctionScorer cs = new AnonymousClassConjunctionScorer(requiredNrMatchers, this, defaultSimilarity);
- System.Collections.IEnumerator rsi = requiredScorers.GetEnumerator();
- while (rsi.MoveNext())
- {
- cs.Add((Scorer) rsi.Current);
- }
- return cs;
- }
-
- private Scorer DualConjunctionSumScorer(Scorer req1, Scorer req2)
- {
- // non counting.
- //UPGRADE_NOTE: Final was removed from the declaration of 'requiredNrMatchers '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
- int requiredNrMatchers = requiredScorers.Count;
- ConjunctionScorer cs = new ConjunctionScorer(defaultSimilarity);
- // All scorers match, so defaultSimilarity super.score() always has 1 as
- // the coordination factor.
- // Therefore the sum of the scores of two scorers
- // is used as score.
- cs.Add(req1);
- cs.Add(req2);
- return cs;
- }
-
- /// <summary>Returns the scorer to be used for match counting and score summing.
- /// Uses requiredScorers, optionalScorers and prohibitedScorers.
- /// </summary>
- private Scorer MakeCountingSumScorer()
- {
- // each scorer counted as a single matcher
- return (requiredScorers.Count == 0)?MakeCountingSumScorerNoReq():MakeCountingSumScorerSomeReq();
- }
-
- private Scorer MakeCountingSumScorerNoReq()
- {
- // No required scorers
- if (optionalScorers.Count == 0)
- {
- return new NonMatchingScorer(); // no clauses or only prohibited clauses
- }
- else
- {
- // No required scorers. At least one optional scorer.
- // minNrShouldMatch optional scorers are required, but at least 1
- int nrOptRequired = (minNrShouldMatch < 1)?1:minNrShouldMatch;
- if (optionalScorers.Count < nrOptRequired)
- {
- return new NonMatchingScorer(); // fewer optional clauses than minimum (at least 1) that should match
- }
- else
- {
- // optionalScorers.size() >= nrOptRequired, no required scorers
- Scorer requiredCountingSumScorer = (optionalScorers.Count > nrOptRequired)?CountingDisjunctionSumScorer(optionalScorers, nrOptRequired):((optionalScorers.Count == 1)?new SingleMatchScorer(this, (Scorer) optionalScorers[0]):CountingConjunctionSumScorer(optionalScorers));
- return AddProhibitedScorers(requiredCountingSumScorer);
- }
- }
- }
-
- private Scorer MakeCountingSumScorerSomeReq()
- {
- // At least one required scorer.
- if (optionalScorers.Count < minNrShouldMatch)
- {
- return new NonMatchingScorer(); // fewer optional clauses than minimum that should match
- }
- else if (optionalScorers.Count == minNrShouldMatch)
- {
- // all optional scorers also required.
- System.Collections.ArrayList allReq = new System.Collections.ArrayList(requiredScorers);
- allReq.AddRange(optionalScorers);
- return AddProhibitedScorers(CountingConjunctionSumScorer(allReq));
- }
- else
- {
- // optionalScorers.size() > minNrShouldMatch, and at least one required scorer
- Scorer requiredCountingSumScorer = (requiredScorers.Count == 1)?new SingleMatchScorer(this, (Scorer) requiredScorers[0]):CountingConjunctionSumScorer(requiredScorers);
- if (minNrShouldMatch > 0)
- {
- // use a required disjunction scorer over the optional scorers
- return AddProhibitedScorers(DualConjunctionSumScorer(requiredCountingSumScorer, CountingDisjunctionSumScorer(optionalScorers, minNrShouldMatch)));
- }
- else
- {
- // minNrShouldMatch == 0
- return new ReqOptSumScorer(AddProhibitedScorers(requiredCountingSumScorer), ((optionalScorers.Count == 1)?new SingleMatchScorer(this, (Scorer) optionalScorers[0]):CountingDisjunctionSumScorer(optionalScorers, 1))); // require 1 in combined, optional scorer.
- }
- }
- }
-
- /// <summary>Returns the scorer to be used for match counting and score summing.
- /// Uses the given required scorer and the prohibitedScorers.
- /// </summary>
- /// <param name="requiredCountingSumScorer">A required scorer already built.
- /// </param>
- private Scorer AddProhibitedScorers(Scorer requiredCountingSumScorer)
- {
- return (prohibitedScorers.Count == 0)?requiredCountingSumScorer:new ReqExclScorer(requiredCountingSumScorer, ((prohibitedScorers.Count == 1)?(Scorer) prohibitedScorers[0]:new DisjunctionSumScorer(prohibitedScorers)));
- }
-
- /// <summary>Scores and collects all matching documents.</summary>
- /// <param name="hc">The collector to which all matching documents are passed through
- /// {@link HitCollector#Collect(int, float)}.
- /// <br>When this method is used the {@link #Explain(int)} method should not be used.
- /// </param>
- public override void Score(HitCollector hc)
- {
- if (countingSumScorer == null)
- {
- InitCountingSumScorer();
- }
- while (countingSumScorer.Next())
- {
- hc.Collect(countingSumScorer.Doc(), Score());
- }
- }
-
- /// <summary>Expert: Collects matching documents in a range.
- /// <br>Note that {@link #Next()} must be called once before this method is
- /// called for the first time.
- /// </summary>
- /// <param name="hc">The collector to which all matching documents are passed through
- /// {@link HitCollector#Collect(int, float)}.
- /// </param>
- /// <param name="max">Do not score documents past this.
- /// </param>
- /// <returns> true if more matching documents may remain.
- /// </returns>
- protected internal override bool Score(HitCollector hc, int max)
- {
- // null pointer exception when Next() was not called before:
- int docNr = countingSumScorer.Doc();
- while (docNr < max)
- {
- hc.Collect(docNr, Score());
- if (!countingSumScorer.Next())
- {
- return false;
- }
- docNr = countingSumScorer.Doc();
- }
- return true;
- }
-
- public override int Doc()
- {
- return countingSumScorer.Doc();
- }
-
- public override bool Next()
- {
- if (countingSumScorer == null)
- {
- InitCountingSumScorer();
- }
- return countingSumScorer.Next();
- }
-
- public override float Score()
- {
- coordinator.InitDoc();
- float sum = countingSumScorer.Score();
- return sum * coordinator.CoordFactor();
- }
-
- /// <summary>Skips to the first match beyond the current whose document number is
- /// greater than or equal to a given target.
- ///
- /// <p>When this method is used the {@link #Explain(int)} method should not be used.
- ///
- /// </summary>
- /// <param name="target">The target document number.
- /// </param>
- /// <returns> true iff there is such a match.
- /// </returns>
- public override bool SkipTo(int target)
- {
- if (countingSumScorer == null)
- {
- InitCountingSumScorer();
- }
- return countingSumScorer.SkipTo(target);
- }
-
- /// <summary>Throws an UnsupportedOperationException.
- /// TODO: Implement an explanation of the coordination factor.
- /// </summary>
- /// <param name="doc">The document number for the explanation.
- /// </param>
- /// <throws> UnsupportedOperationException </throws>
- public override Explanation Explain(int doc)
- {
- throw new System.NotSupportedException();
- /* How to explain the coordination factor?
- initCountingSumScorer();
- return countingSumScorer.explain(doc); // misses coord factor.
- */
- }
- }
- }