20 using Lucene.Net.Index;
25 using Query = Lucene.Net.Search.Query;
26 using Scorer = Lucene.Net.Search.Scorer;
29 using Weight = Lucene.Net.Search.Weight;
31 namespace Lucene.Net.Search.Function
52 private Query subQuery;
54 private bool strict =
false;
83 public CustomScoreQuery(
Query subQuery, params ValueSourceQuery[] valSrcQueries)
85 this.subQuery = subQuery;
86 this.valSrcQueries = valSrcQueries != null?valSrcQueries:
new ValueSourceQuery[0];
88 throw new System.ArgumentException(
"<subquery> must not be null!");
103 for (
int i = 0; i < valSrcQueries.Length; i++)
106 if (v != valSrcQueries[i])
109 clone.valSrcQueries[i] = v;
113 return (clone == null) ?
this : clone;
117 public override void ExtractTerms(System.Collections.Generic.ISet<
Term> terms)
120 for (
int i = 0; i < valSrcQueries.Length; i++)
122 valSrcQueries[i].ExtractTerms(terms);
127 public override System.Object Clone()
132 for (
int i = 0; i < valSrcQueries.Length; i++)
140 public override System.String ToString(System.String field)
142 System.Text.StringBuilder sb =
new System.Text.StringBuilder(Name()).Append(
"(");
143 sb.Append(subQuery.
ToString(field));
144 for (
int i = 0; i < valSrcQueries.Length; i++)
146 sb.Append(
", ").Append(valSrcQueries[i].ToString(field));
149 sb.Append(strict?
" STRICT":
"");
154 public override bool Equals(System.Object o)
156 if (GetType() != o.GetType())
161 if (this.Boost != other.
Boost ||
162 !
this.subQuery.Equals(other.subQuery) ||
163 this.strict != other.strict ||
164 this.valSrcQueries.Length != other.valSrcQueries.Length)
170 return valSrcQueries.SequenceEqual(other.valSrcQueries);
174 public override int GetHashCode()
177 for (
int i = 0; i < valSrcQueries.Length; i++)
182 return (GetType().GetHashCode() + subQuery.
GetHashCode() + valSrcHash) ^
183 BitConverter.ToInt32(BitConverter.GetBytes(Boost), 0) ^ (strict ? 1234 : 4321);
195 return new AnonymousCustomScoreProvider(
this, reader);
203 this.parent = parent;
205 public override float CustomScore(
int doc,
float subQueryScore,
float[] valSrcScores)
207 return parent.
CustomScore(doc, subQueryScore, valSrcScores);
210 public override float CustomScore(
int doc,
float subQueryScore,
float valSrcScore)
212 return parent.CustomScore(doc, subQueryScore, valSrcScore);
217 return parent.CustomExplain(doc, subQueryExpl, valSrcExpls);
222 return parent.CustomExplain(doc, subQueryExpl, valSrcExpl);
236 [Obsolete(
"Will be removed in Lucene 3.1")]
237 public virtual float CustomScore(
int doc,
float subQueryScore,
float[] valSrcScores)
239 if (valSrcScores.Length == 1)
241 return CustomScore(doc, subQueryScore, valSrcScores[0]);
243 if (valSrcScores.Length == 0)
245 return CustomScore(doc, subQueryScore, 1);
247 float score = subQueryScore;
248 for (
int i = 0; i < valSrcScores.Length; i++)
250 score *= valSrcScores[i];
263 [Obsolete(
"Will be removed in Lucene 3.1")]
264 public virtual float CustomScore(
int doc,
float subQueryScore,
float valSrcScore)
266 return subQueryScore * valSrcScore;
278 [Obsolete(
"Will be removed in Lucene 3.1")]
281 if (valSrcExpls.Length == 1)
283 return CustomExplain(doc, subQueryExpl, valSrcExpls[0]);
285 if (valSrcExpls.Length == 0)
289 float valSrcScore = 1;
290 for (
int i = 0; i < valSrcExpls.Length; i++)
292 valSrcScore *= valSrcExpls[i].
Value;
296 for (
int i = 0; i < valSrcExpls.Length; i++)
309 [Obsolete(
"Will be removed in Lucene 3.1")]
312 float valSrcScore = 1;
313 if (valSrcExpl != null)
315 valSrcScore *= valSrcExpl.
Value;
326 private class CustomWeight:
Weight
330 this.enclosingInstance = enclosingInstance;
332 private CustomScoreQuery enclosingInstance;
333 public CustomScoreQuery Enclosing_Instance
337 return enclosingInstance;
342 internal Weight subQueryWeight;
343 internal Weight[] valSrcWeights;
344 internal bool qStrict;
346 public CustomWeight(CustomScoreQuery enclosingInstance,
Searcher searcher)
348 InitBlock(enclosingInstance);
349 this.similarity = Enclosing_Instance.GetSimilarity(searcher);
350 this.subQueryWeight = Enclosing_Instance.subQuery.Weight(searcher);
351 this.valSrcWeights =
new Weight[Enclosing_Instance.valSrcQueries.Length];
352 for (
int i = 0; i < Enclosing_Instance.valSrcQueries.Length; i++)
354 this.valSrcWeights[i] = Enclosing_Instance.valSrcQueries[i].CreateWeight(searcher);
356 this.qStrict = Enclosing_Instance.strict;
363 get {
return Enclosing_Instance; }
368 public override float Value
370 get {
return Enclosing_Instance.Boost; }
375 public override float GetSumOfSquaredWeights()
377 float sum = subQueryWeight.GetSumOfSquaredWeights();
378 for (
int i = 0; i < valSrcWeights.Length; i++)
382 var sumsq = valSrcWeights[i].GetSumOfSquaredWeights();
387 sum += valSrcWeights[i].GetSumOfSquaredWeights();
390 sum *= Enclosing_Instance.Boost*Enclosing_Instance.Boost;
395 public override void Normalize(
float norm)
397 norm *= Enclosing_Instance.Boost;
398 subQueryWeight.Normalize(norm);
399 for (
int i = 0; i < valSrcWeights.Length; i++)
403 valSrcWeights[i].Normalize(1);
407 valSrcWeights[i].Normalize(norm);
419 Scorer subQueryScorer = subQueryWeight.Scorer(reader,
true,
false);
420 if (subQueryScorer == null)
424 Scorer[] valSrcScorers =
new Scorer[valSrcWeights.Length];
425 for (
int i = 0; i < valSrcScorers.Length; i++)
427 valSrcScorers[i] = valSrcWeights[i].Scorer(reader,
true, topScorer);
429 return new CustomScorer(enclosingInstance, similarity, reader,
this, subQueryScorer, valSrcScorers);
435 return explain == null?
new Explanation(0.0f,
"no matching docs"):explain;
440 Explanation subQueryExpl = subQueryWeight.Explain(reader, doc);
441 if (!subQueryExpl.IsMatch)
447 for (
int i = 0; i < valSrcWeights.Length; i++)
449 valSrcExpls[i] = valSrcWeights[i].Explain(reader, doc);
451 Explanation customExp = Enclosing_Instance.GetCustomScoreProvider(reader).CustomExplain(doc, subQueryExpl, valSrcExpls);
452 float sc = Value * customExp.Value;
454 res.AddDetail(customExp);
455 res.AddDetail(
new Explanation(Value,
"queryBoost"));
459 public override bool GetScoresDocsOutOfOrder()
469 private class CustomScorer:
Scorer
471 private void InitBlock(CustomScoreQuery enclosingInstance)
473 this.enclosingInstance = enclosingInstance;
475 private CustomScoreQuery enclosingInstance;
476 public CustomScoreQuery Enclosing_Instance
480 return enclosingInstance;
484 private float qWeight;
485 private Scorer subQueryScorer;
486 private Scorer[] valSrcScorers;
488 private CustomScoreProvider provider;
489 private float[] vScores;
492 internal CustomScorer(CustomScoreQuery enclosingInstance,
Similarity similarity,
IndexReader reader, CustomWeight w,
Scorer subQueryScorer,
Scorer[] valSrcScorers):base(similarity)
494 InitBlock(enclosingInstance);
495 this.qWeight = w.Value;
496 this.subQueryScorer = subQueryScorer;
497 this.valSrcScorers = valSrcScorers;
498 this.reader = reader;
499 this.vScores =
new float[valSrcScorers.Length];
500 this.provider = this.Enclosing_Instance.GetCustomScoreProvider(reader);
503 public override int NextDoc()
505 int doc = subQueryScorer.NextDoc();
506 if (doc != NO_MORE_DOCS)
508 for (
int i = 0; i < valSrcScorers.Length; i++)
510 valSrcScorers[i].Advance(doc);
516 public override int DocID()
518 return subQueryScorer.DocID();
522 public override float Score()
524 for (
int i = 0; i < valSrcScorers.Length; i++)
526 vScores[i] = valSrcScorers[i].Score();
528 return qWeight * provider.CustomScore(subQueryScorer.DocID(), subQueryScorer.Score(), vScores);
531 public override int Advance(
int target)
533 int doc = subQueryScorer.Advance(target);
534 if (doc != NO_MORE_DOCS)
536 for (
int i = 0; i < valSrcScorers.Length; i++)
538 valSrcScorers[i].Advance(doc);
547 return new CustomWeight(
this, searcher);
558 public virtual bool IsStrict()
568 public virtual void SetStrict(
bool strict)
570 this.strict = strict;
574 public virtual System.String Name()