2 * Copyright 2002-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
;
20 namespace Lucene
.Net
.Search
23 /// <summary>The abstract base class for queries.
24 /// <p>Instantiable subclasses are:
26 /// <li> {@link TermQuery}
27 /// <li> {@link MultiTermQuery}
28 /// <li> {@link BooleanQuery}
29 /// <li> {@link WildcardQuery}
30 /// <li> {@link PhraseQuery}
31 /// <li> {@link PrefixQuery}
32 /// <li> {@link MultiPhraseQuery}
33 /// <li> {@link FuzzyQuery}
34 /// <li> {@link RangeQuery}
35 /// <li> {@link Lucene.Net.search.spans.SpanQuery}
37 /// <p>A parser for queries is contained in:
39 /// <li>{@link Lucene.Net.queryParser.QueryParser QueryParser}
43 public abstract class Query
: System
.ICloneable
45 private float boost
= 1.0f
; // query boost factor
47 /// <summary>Sets the boost for this query clause to <code>b</code>. Documents
48 /// matching this clause will (in addition to the normal weightings) have
49 /// their score multiplied by <code>b</code>.
51 public virtual void SetBoost(float b
)
56 /// <summary>Gets the boost for this clause. Documents matching
57 /// this clause will (in addition to the normal weightings) have their score
58 /// multiplied by <code>b</code>. The boost is 1.0 by default.
60 public virtual float GetBoost()
65 /// <summary>Prints a query to a string, with <code>field</code> as the default field
66 /// for terms. <p>The representation used is one that is supposed to be readable
67 /// by {@link Lucene.Net.queryParser.QueryParser QueryParser}. However,
68 /// there are the following limitations:
70 /// <li>If the query was created by the parser, the printed
71 /// representation may not be exactly what was parsed. For example,
72 /// characters that need to be escaped will be represented without
73 /// the required backslash.</li>
74 /// <li>Some of the more complicated queries (e.g. span queries)
75 /// don't have a representation that can be parsed by QueryParser.</li>
78 public abstract System
.String
ToString(System
.String field
);
80 /// <summary>Prints a query to a string. </summary>
81 public override System
.String
ToString()
86 /// <summary>Expert: Constructs an appropriate Weight implementation for this query.
88 /// <p>Only implemented by primitive queries, which re-write to themselves.
90 protected internal virtual Weight
CreateWeight(Searcher searcher
)
92 throw new System
.NotSupportedException();
95 /// <summary>Expert: Constructs and initializes a Weight for a top-level query. </summary>
96 public virtual Weight
Weight(Searcher searcher
)
98 Query query
= searcher
.Rewrite(this);
99 Weight weight
= query
.CreateWeight(searcher
);
100 float sum
= weight
.SumOfSquaredWeights();
101 float norm
= GetSimilarity(searcher
).QueryNorm(sum
);
102 weight
.Normalize(norm
);
106 /// <summary>Expert: called to re-write queries into primitive queries. For example,
107 /// a PrefixQuery will be rewritten into a BooleanQuery that consists
110 public virtual Query
Rewrite(IndexReader reader
)
115 /// <summary>Expert: called when re-writing queries under MultiSearcher.
117 /// Create a single query suitable for use by all subsearchers (in 1-1
118 /// correspondence with queries). This is an optimization of the OR of
119 /// all queries. We handle the common optimization cases of equal
120 /// queries and overlapping clauses of boolean OR queries (as generated
121 /// by MultiTermQuery.rewrite() and RangeQuery.rewrite()).
122 /// Be careful overriding this method as queries[0] determines which
123 /// method will be called and is not necessarily of the same type as
124 /// the other queries.
126 public virtual Query
Combine(Query
[] queries
)
128 System
.Collections
.Hashtable uniques
= new System
.Collections
.Hashtable();
129 for (int i
= 0; i
< queries
.Length
; i
++)
131 Query query
= queries
[i
];
132 BooleanClause
[] clauses
= null;
133 // check if we can split the query into clauses
134 bool splittable
= (query
is BooleanQuery
);
137 BooleanQuery bq
= (BooleanQuery
) query
;
138 splittable
= bq
.IsCoordDisabled();
139 clauses
= bq
.GetClauses();
140 for (int j
= 0; splittable
&& j
< clauses
.Length
; j
++)
142 splittable
= (clauses
[j
].GetOccur() == BooleanClause
.Occur
.SHOULD
);
147 for (int j
= 0; j
< clauses
.Length
; j
++)
149 Query tmp
= clauses
[j
].GetQuery();
150 if (uniques
.Contains(tmp
) == false)
152 uniques
.Add(tmp
, tmp
);
158 if (uniques
.Contains(query
) == false)
160 uniques
.Add(query
, query
);
164 // optimization: if we have just one query, just return it
165 if (uniques
.Count
== 1)
167 System
.Collections
.IDictionaryEnumerator iter
= uniques
.GetEnumerator();
169 return iter
.Value
as Query
;
171 System
.Collections
.IDictionaryEnumerator it
= uniques
.GetEnumerator();
172 BooleanQuery result
= new BooleanQuery(true);
173 while (it
.MoveNext())
175 result
.Add((Query
) it
.Value
, BooleanClause
.Occur
.SHOULD
);
180 /// <summary> Expert: adds all terms occuring in this query to the terms set. Only
181 /// works if this query is in its {@link #rewrite rewritten} form.
184 /// <throws> UnsupportedOperationException if this query is not yet rewritten </throws>
185 public virtual void ExtractTerms(System
.Collections
.Hashtable terms
)
187 // needs to be implemented by query subclasses
188 throw new System
.NotSupportedException();
192 /// <summary>Expert: merges the clauses of a set of BooleanQuery's into a single
195 /// <p>A utility for use by {@link #Combine(Query[])} implementations.
197 public static Query
MergeBooleanQueries(Query
[] queries
)
199 System
.Collections
.Hashtable allClauses
= new System
.Collections
.Hashtable();
200 for (int i
= 0; i
< queries
.Length
; i
++)
202 BooleanClause
[] clauses
= ((BooleanQuery
) queries
[i
]).GetClauses();
203 for (int j
= 0; j
< clauses
.Length
; j
++)
205 allClauses
.Add(clauses
[j
], clauses
[j
]);
209 bool coordDisabled
= queries
.Length
== 0 ? false : ((BooleanQuery
) queries
[0]).IsCoordDisabled();
210 BooleanQuery result
= new BooleanQuery(coordDisabled
);
211 foreach (BooleanClause booleanClause
in allClauses
.Keys
)
213 result
.Add(booleanClause
);
218 /// <summary>Expert: Returns the Similarity implementation to be used for this query.
219 /// Subclasses may override this method to specify their own Similarity
220 /// implementation, perhaps one that delegates through that of the Searcher.
221 /// By default the Searcher's Similarity implementation is returned.
223 public virtual Similarity
GetSimilarity(Searcher searcher
)
225 return searcher
.GetSimilarity();
228 /// <summary>Returns a clone of this query. </summary>
229 public virtual System
.Object
Clone()
233 return (Query
) base.MemberwiseClone();
235 catch (System
.Exception e
)
237 throw new System
.SystemException("Clone not supported: " + e
.Message
);