19 using Lucene.Net.Support;
22 using Term = Lucene.Net.Index.Term;
26 namespace Lucene.Net.Search
42 private System.String field;
43 private System.Collections.Generic.List<
Term[]> termArrays =
new System.Collections.Generic.List<
Term[]>();
44 private System.Collections.Generic.List<
int> positions =
new System.Collections.Generic.List<
int>();
51 public virtual int Slop
60 public virtual void Add(
Term term)
62 Add(
new Term[]{term});
71 public virtual void Add(
Term[] terms)
74 if (positions.Count > 0)
75 position = positions[positions.Count - 1] + 1;
89 public virtual void Add(
Term[] terms,
int position)
91 if (termArrays.Count == 0)
92 field = terms[0].Field;
94 for (
int i = 0; i < terms.Length; i++)
96 if ((System.Object) terms[i].Field != (System.Object) field)
98 throw new System.ArgumentException(
"All phrase terms must be in the same field (" + field +
"): " + terms[i]);
102 termArrays.Add(terms);
103 positions.Add(position);
109 [System.Diagnostics.CodeAnalysis.SuppressMessage(
"Microsoft.Design",
"CA1024:UsePropertiesWhereAppropriate")]
110 public virtual System.Collections.Generic.IList<
Term[]> GetTermArrays()
112 return termArrays.AsReadOnly();
116 public virtual int[] GetPositions()
118 int[] result =
new int[positions.Count];
119 for (
int i = 0; i < positions.Count; i++)
120 result[i] = positions[i];
125 public override void ExtractTerms(System.Collections.Generic.ISet<
Term> terms)
127 foreach(
Term[] arr
in termArrays)
129 terms.UnionWith(arr);
135 private class MultiPhraseWeight:
Weight
139 this.enclosingInstance = enclosingInstance;
146 return enclosingInstance;
151 private float value_Renamed;
153 private float queryNorm;
154 private float queryWeight;
158 InitBlock(enclosingInstance);
159 this.similarity = Enclosing_Instance.GetSimilarity(searcher);
162 int maxDoc = searcher.MaxDoc;
163 foreach (
Term[] terms
in enclosingInstance.termArrays)
165 foreach (
Term term
in terms)
167 idf += similarity.Idf(searcher.DocFreq(term), maxDoc);
174 get {
return Enclosing_Instance; }
177 public override float Value
179 get {
return value_Renamed; }
182 public override float GetSumOfSquaredWeights()
184 queryWeight = idf*Enclosing_Instance.Boost;
185 return queryWeight*queryWeight;
188 public override void Normalize(
float queryNorm)
190 this.queryNorm = queryNorm;
191 queryWeight *= queryNorm;
192 value_Renamed = queryWeight * idf;
197 if (Enclosing_Instance.termArrays.Count == 0)
202 for (
int i = 0; i < tps.Length; i++)
204 Term[] terms = Enclosing_Instance.termArrays[i];
207 if (terms.Length > 1)
210 p = reader.TermPositions(terms[0]);
218 if (Enclosing_Instance.slop == 0)
219 return new ExactPhraseScorer(
this, tps, Enclosing_Instance.GetPositions(), similarity, reader.Norms(Enclosing_Instance.field));
221 return new SloppyPhraseScorer(
this, tps, Enclosing_Instance.GetPositions(), similarity, Enclosing_Instance.slop, reader.Norms(Enclosing_Instance.field));
227 result.Description =
"weight(" +
Query +
" in " + doc +
"), product of:";
233 queryExpl.Description =
"queryWeight(" +
Query +
"), product of:";
236 if (Enclosing_Instance.Boost != 1.0f)
237 queryExpl.AddDetail(boostExpl);
239 queryExpl.AddDetail(idfExpl);
242 queryExpl.AddDetail(queryNormExpl);
244 queryExpl.Value = boostExpl.Value * idfExpl.Value * queryNormExpl.Value;
246 result.AddDetail(queryExpl);
250 fieldExpl.Description =
"fieldWeight(" +
Query +
" in " + doc +
"), product of:";
252 PhraseScorer scorer = (PhraseScorer)
Scorer(reader,
true,
false);
258 int d = scorer.Advance(doc);
259 float phraseFreq = (d == doc) ? scorer.CurrentFreq() : 0.0f;
260 tfExplanation.Value = similarity.Tf(phraseFreq);
261 tfExplanation.Description =
"tf(phraseFreq=" + phraseFreq +
")";
262 fieldExpl.AddDetail(tfExplanation);
263 fieldExpl.AddDetail(idfExpl);
266 byte[] fieldNorms = reader.Norms(Enclosing_Instance.field);
267 float fieldNorm = fieldNorms != null?
Similarity.DecodeNorm(fieldNorms[doc]):1.0f;
268 fieldNormExpl.Value = fieldNorm;
269 fieldNormExpl.Description =
"fieldNorm(field=" + Enclosing_Instance.field +
", doc=" + doc +
")";
270 fieldExpl.AddDetail(fieldNormExpl);
272 fieldExpl.Match = tfExplanation.IsMatch;
273 fieldExpl.Value = tfExplanation.Value * idfExpl.Value * fieldNormExpl.Value;
275 result.AddDetail(fieldExpl);
276 System.Boolean? tempAux = fieldExpl.Match;
277 result.Match = tempAux;
280 result.Value = queryExpl.Value * fieldExpl.Value;
282 if (queryExpl.Value == 1.0f)
291 if (termArrays.Count == 1)
294 Term[] terms = termArrays[0];
296 for (
int i = 0; i < terms.Length; i++)
311 return new MultiPhraseWeight(
this, searcher);
315 public override System.String ToString(System.String f)
317 System.Text.StringBuilder buffer =
new System.Text.StringBuilder();
318 if (!field.Equals(f))
320 buffer.Append(field);
325 System.Collections.Generic.IEnumerator<
Term[]> i = termArrays.GetEnumerator();
338 Term[] terms = i.Current;
339 if (terms.Length > 1)
342 for (
int j = 0; j < terms.Length; j++)
344 buffer.Append(terms[j].Text);
345 if (j < terms.Length - 1)
352 buffer.Append(terms[0].Text);
365 return buffer.ToString();
370 public override bool Equals(System.Object o)
375 bool eq = this.Boost == other.
Boost && this.slop == other.slop;
380 eq = this.termArrays.Count.Equals(other.termArrays.Count);
386 for (
int i = 0; i < this.termArrays.Count; i++)
397 eq = this.positions.Count.Equals(other.positions.Count);
402 for (
int i = 0; i < this.positions.Count; i++)
404 if (!((
int)this.positions[i] == (
int)other.positions[i]))
413 public override int GetHashCode()
416 foreach(
int pos
in positions)
418 posHash += pos.GetHashCode();
420 return BitConverter.ToInt32(BitConverter.GetBytes(Boost), 0) ^ slop ^ TermArraysHashCode() ^ posHash ^ 0x4AC65113;
424 private int TermArraysHashCode()
427 foreach(
Term[] termArray
in termArrays)
430 hashCode = 31*hashCode + (termArray == null ? 0 : ArraysHashCode(termArray));
435 private int ArraysHashCode(
Term[] termArray)
437 if (termArray == null)
442 for (
int i = 0; i < termArray.Length; i++)
444 Term term = termArray[i];
445 result = 31 * result + (term == null?0:term.GetHashCode());
452 private bool TermArraysEquals(System.Collections.Generic.List<
Term[]> termArrays1, System.Collections.Generic.List<
Term[]> termArrays2)
454 if (termArrays1.Count != termArrays2.Count)
458 var iterator1 = termArrays1.GetEnumerator();
459 var iterator2 = termArrays2.GetEnumerator();
460 while (iterator1.MoveNext())
462 Term[] termArray1 = iterator1.Current;
463 Term[] termArray2 = iterator2.Current;
464 if (!(termArray1 == null ? termArray2 == null : TermEquals(termArray1, termArray2)))
472 public static bool TermEquals(System.Array array1, System.Array array2)
475 if ((array1 == null) && (array2 == null))
477 else if ((array1 != null) && (array2 != null))
479 if (array1.Length == array2.Length)
481 int length = array1.Length;
483 for (
int index = 0; index < length; index++)
485 if (!(array1.GetValue(index).Equals(array2.GetValue(index))))