2
* Copyright 2004 The Apache Software Foundation
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
18
using IndexReader = Lucene.Net.Index.IndexReader;
19
using MultipleTermPositions = Lucene.Net.Index.MultipleTermPositions;
20
using Term = Lucene.Net.Index.Term;
21
using TermPositions = Lucene.Net.Index.TermPositions;
22
using ToStringUtils = Lucene.Net.Util.ToStringUtils;
24
namespace Lucene.Net.Search
27
/// <summary> PhrasePrefixQuery is a generalized version of PhraseQuery, with an added
28
/// method {@link #Add(Term[])}.
29
/// To use this class, to search for the phrase "Microsoft app*" first use
30
/// add(Term) on the term "Microsoft", then find all terms that has "app" as
31
/// prefix using IndexReader.terms(Term), and use PhrasePrefixQuery.add(Term[]
32
/// terms) to add them to the query.
35
/// <deprecated> use {@link Lucene.Net.search.MultiPhraseQuery} instead
37
/// <author> Anders Nielsen
42
public class PhrasePrefixQuery : Query
44
private System.String field;
45
private System.Collections.ArrayList termArrays = new System.Collections.ArrayList();
46
private System.Collections.ArrayList positions = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
50
/// <summary>Sets the phrase slop for this query.</summary>
51
/// <seealso cref="PhraseQuery.SetSlop(int)">
53
public virtual void SetSlop(int s)
58
/// <summary>Sets the phrase slop for this query.</summary>
59
/// <seealso cref="PhraseQuery.GetSlop()">
61
public virtual int GetSlop()
66
/// <summary>Add a single term at the next position in the phrase.</summary>
67
/// <seealso cref="PhraseQuery.Add(Term)">
69
public virtual void Add(Term term)
71
Add(new Term[]{term});
74
/// <summary>Add multiple terms at the next position in the phrase. Any of the terms
78
/// <seealso cref="PhraseQuery.Add(Term)">
80
public virtual void Add(Term[] terms)
83
if (positions.Count > 0)
84
position = ((System.Int32) positions[positions.Count - 1]) + 1;
89
/// <summary> Allows to specify the relative position of terms within the phrase.
92
/// <seealso cref="PhraseQuery.Add(Term, int)">
94
/// <param name="terms">
96
/// <param name="position">
98
public virtual void Add(Term[] terms, int position)
100
if (termArrays.Count == 0)
101
field = terms[0].Field();
103
for (int i = 0; i < terms.Length; i++)
105
if (terms[i].Field() != field)
107
throw new System.ArgumentException("All phrase terms must be in the same field (" + field + "): " + terms[i]);
111
termArrays.Add(terms);
112
positions.Add((System.Int32) position);
115
/// <summary> Returns the relative positions of terms in this phrase.</summary>
116
public virtual int[] GetPositions()
118
int[] result = new int[positions.Count];
119
for (int i = 0; i < positions.Count; i++)
120
result[i] = ((System.Int32) positions[i]);
125
private class PhrasePrefixWeight : Weight
127
private void InitBlock(PhrasePrefixQuery enclosingInstance)
129
this.enclosingInstance = enclosingInstance;
131
private PhrasePrefixQuery enclosingInstance;
132
public PhrasePrefixQuery Enclosing_Instance
136
return enclosingInstance;
140
private Similarity similarity;
141
private float value_Renamed;
143
private float queryNorm;
144
private float queryWeight;
146
public PhrasePrefixWeight(PhrasePrefixQuery enclosingInstance, Searcher searcher)
148
InitBlock(enclosingInstance);
149
this.similarity = Enclosing_Instance.GetSimilarity(searcher);
152
System.Collections.IEnumerator i = Enclosing_Instance.termArrays.GetEnumerator();
155
Term[] terms = (Term[]) i.Current;
156
for (int j = 0; j < terms.Length; j++)
158
idf += Enclosing_Instance.GetSimilarity(searcher).Idf(terms[j], searcher);
163
public virtual Query GetQuery()
165
return Enclosing_Instance;
167
public virtual float GetValue()
169
return value_Renamed;
172
public virtual float SumOfSquaredWeights()
174
queryWeight = idf * Enclosing_Instance.GetBoost(); // compute query weight
175
return queryWeight * queryWeight; // square it
178
public virtual void Normalize(float queryNorm)
180
this.queryNorm = queryNorm;
181
queryWeight *= queryNorm; // normalize query weight
182
value_Renamed = queryWeight * idf; // idf for document
185
public virtual Scorer Scorer(IndexReader reader)
187
if (Enclosing_Instance.termArrays.Count == 0)
188
// optimize zero-term case
191
TermPositions[] tps = new TermPositions[Enclosing_Instance.termArrays.Count];
192
for (int i = 0; i < tps.Length; i++)
194
Term[] terms = (Term[]) Enclosing_Instance.termArrays[i];
197
if (terms.Length > 1)
198
p = new MultipleTermPositions(reader, terms);
200
p = reader.TermPositions(terms[0]);
208
if (Enclosing_Instance.slop == 0)
209
return new ExactPhraseScorer(this, tps, Enclosing_Instance.GetPositions(), similarity, reader.Norms(Enclosing_Instance.field));
211
return new SloppyPhraseScorer(this, tps, Enclosing_Instance.GetPositions(), similarity, Enclosing_Instance.slop, reader.Norms(Enclosing_Instance.field));
214
public virtual Explanation Explain(IndexReader reader, int doc)
216
Explanation result = new Explanation();
217
result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:");
219
Explanation idfExpl = new Explanation(idf, "idf(" + GetQuery() + ")");
221
// explain query weight
222
Explanation queryExpl = new Explanation();
223
queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:");
225
Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost");
226
if (Enclosing_Instance.GetBoost() != 1.0f)
227
queryExpl.AddDetail(boostExpl);
229
queryExpl.AddDetail(idfExpl);
231
Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm");
232
queryExpl.AddDetail(queryNormExpl);
234
queryExpl.SetValue(boostExpl.GetValue() * idfExpl.GetValue() * queryNormExpl.GetValue());
236
result.AddDetail(queryExpl);
238
// explain field weight
239
Explanation fieldExpl = new Explanation();
240
fieldExpl.SetDescription("fieldWeight(" + GetQuery() + " in " + doc + "), product of:");
242
Explanation tfExpl = Scorer(reader).Explain(doc);
243
fieldExpl.AddDetail(tfExpl);
244
fieldExpl.AddDetail(idfExpl);
246
Explanation fieldNormExpl = new Explanation();
247
byte[] fieldNorms = reader.Norms(Enclosing_Instance.field);
248
float fieldNorm = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]):0.0f;
249
fieldNormExpl.SetValue(fieldNorm);
250
fieldNormExpl.SetDescription("fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")");
251
fieldExpl.AddDetail(fieldNormExpl);
253
fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue());
255
result.AddDetail(fieldExpl);
258
result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue());
260
if (queryExpl.GetValue() == 1.0f)
267
protected internal override Weight CreateWeight(Searcher searcher)
269
if (termArrays.Count == 1)
271
// optimize one-term case
272
Term[] terms = (Term[]) termArrays[0];
273
BooleanQuery boq = new BooleanQuery(true);
274
for (int i = 0; i < terms.Length; i++)
276
boq.Add(new TermQuery(terms[i]), BooleanClause.Occur.SHOULD);
278
boq.SetBoost(GetBoost());
279
return boq.CreateWeight(searcher);
281
return new PhrasePrefixWeight(this, searcher);
284
/// <summary>Prints a user-readable version of this query. </summary>
285
public override System.String ToString(System.String f)
287
System.Text.StringBuilder buffer = new System.Text.StringBuilder();
288
if (!field.Equals(f))
290
buffer.Append(field);
295
System.Collections.IEnumerator i = termArrays.GetEnumerator();
298
Term[] terms = (Term[]) i.Current;
299
buffer.Append(terms[0].Text() + (terms.Length > 1?"*":""));
311
buffer.Append(ToStringUtils.Boost(GetBoost()));
313
return buffer.ToString();
b'\\ No newline at end of file'