|
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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;
using IndexReader = Lucene.Net.Index.IndexReader;
namespace Lucene.Net.Search
{
/// <summary>The abstract base class for queries.
/// <p>Instantiable subclasses are:
/// <ul>
/// <li> {@link TermQuery}
/// <li> {@link MultiTermQuery}
/// <li> {@link BooleanQuery}
/// <li> {@link WildcardQuery}
/// <li> {@link PhraseQuery}
/// <li> {@link PrefixQuery}
/// <li> {@link MultiPhraseQuery}
/// <li> {@link FuzzyQuery}
/// <li> {@link RangeQuery}
/// <li> {@link Lucene.Net.Search.Spans.SpanQuery}
/// </ul>
/// <p>A parser for queries is contained in:
/// <ul>
/// <li>{@link Lucene.Net.QueryParsers.QueryParser QueryParser}
/// </ul>
/// </summary>
[Serializable]
public abstract class Query : System.ICloneable
{
private float boost = 1.0f; // query boost factor
/// <summary>Sets the boost for this query clause to <code>b</code>. Documents
/// matching this clause will (in addition to the normal weightings) have
/// their score multiplied by <code>b</code>.
/// </summary>
public virtual void SetBoost(float b)
{
boost = b;
}
/// <summary>Gets the boost for this clause. Documents matching
/// this clause will (in addition to the normal weightings) have their score
/// multiplied by <code>b</code>. The boost is 1.0 by default.
/// </summary>
public virtual float GetBoost()
{
return boost;
}
/// <summary>Prints a query to a string, with <code>field</code> assumed to be the
/// default field and omitted.
/// <p>The representation used is one that is supposed to be readable
/// by {@link Lucene.Net.QueryParsers.QueryParser QueryParser}. However,
/// there are the following limitations:
/// <ul>
/// <li>If the query was created by the parser, the printed
/// representation may not be exactly what was parsed. For example,
/// characters that need to be escaped will be represented without
/// the required backslash.</li>
/// <li>Some of the more complicated queries (e.g. span queries)
/// don't have a representation that can be parsed by QueryParser.</li>
/// </ul>
/// </summary>
public abstract System.String ToString(System.String field);
/// <summary>Prints a query to a string. </summary>
public override System.String ToString()
{
return ToString("");
}
/// <summary>Expert: Constructs an appropriate Weight implementation for this query.
///
/// <p>Only implemented by primitive queries, which re-write to themselves.
/// </summary>
protected internal virtual Weight CreateWeight(Searcher searcher)
{
throw new System.NotSupportedException();
}
/// <summary>Expert: Constructs and initializes a Weight for a top-level query. </summary>
public virtual Weight Weight(Searcher searcher)
{
Query query = searcher.Rewrite(this);
Weight weight = query.CreateWeight(searcher);
float sum = weight.SumOfSquaredWeights();
float norm = GetSimilarity(searcher).QueryNorm(sum);
weight.Normalize(norm);
return weight;
}
/// <summary>Expert: called to re-write queries into primitive queries. For example,
/// a PrefixQuery will be rewritten into a BooleanQuery that consists
/// of TermQuerys.
/// </summary>
public virtual Query Rewrite(IndexReader reader)
{
return this;
}
/// <summary>Expert: called when re-writing queries under MultiSearcher.
///
/// Create a single query suitable for use by all subsearchers (in 1-1
/// correspondence with queries). This is an optimization of the OR of
/// all queries. We handle the common optimization cases of equal
/// queries and overlapping clauses of boolean OR queries (as generated
/// by MultiTermQuery.rewrite() and RangeQuery.rewrite()).
/// Be careful overriding this method as queries[0] determines which
/// method will be called and is not necessarily of the same type as
/// the other queries.
/// </summary>
public virtual Query Combine(Query[] queries)
{
System.Collections.Hashtable uniques = new System.Collections.Hashtable();
for (int i = 0; i < queries.Length; i++)
{
Query query = queries[i];
BooleanClause[] clauses = null;
// check if we can split the query into clauses
bool splittable = (query is BooleanQuery);
if (splittable)
{
BooleanQuery bq = (BooleanQuery) query;
splittable = bq.IsCoordDisabled();
clauses = bq.GetClauses();
for (int j = 0; splittable && j < clauses.Length; j++)
{
splittable = (clauses[j].GetOccur() == BooleanClause.Occur.SHOULD);
}
}
if (splittable)
{
for (int j = 0; j < clauses.Length; j++)
{
Query tmp = clauses[j].GetQuery();
if (uniques.Contains(tmp) == false)
{
uniques.Add(tmp, tmp);
}
}
}
else
{
if (uniques.Contains(query) == false)
{
uniques.Add(query, query);
}
}
}
// optimization: if we have just one query, just return it
if (uniques.Count == 1)
{
System.Collections.IDictionaryEnumerator iter = uniques.GetEnumerator();
iter.MoveNext();
return iter.Value as Query;
}
System.Collections.IDictionaryEnumerator it = uniques.GetEnumerator();
BooleanQuery result = new BooleanQuery(true);
while (it.MoveNext())
{
result.Add((Query) it.Value, BooleanClause.Occur.SHOULD);
}
return result;
}
/// <summary> Expert: adds all terms occuring in this query to the terms set. Only
/// works if this query is in its {@link #rewrite rewritten} form.
///
/// </summary>
/// <throws> UnsupportedOperationException if this query is not yet rewritten </throws>
public virtual void ExtractTerms(System.Collections.Hashtable terms)
{
// needs to be implemented by query subclasses
throw new System.NotSupportedException();
}
/// <summary>Expert: merges the clauses of a set of BooleanQuery's into a single
/// BooleanQuery.
///
/// <p>A utility for use by {@link #Combine(Query[])} implementations.
/// </summary>
public static Query MergeBooleanQueries(Query[] queries)
{
System.Collections.Hashtable allClauses = new System.Collections.Hashtable();
for (int i = 0; i < queries.Length; i++)
{
BooleanClause[] clauses = ((BooleanQuery) queries[i]).GetClauses();
for (int j = 0; j < clauses.Length; j++)
{
allClauses.Add(clauses[j], clauses[j]);
}
}
bool coordDisabled = queries.Length == 0 ? false : ((BooleanQuery) queries[0]).IsCoordDisabled();
BooleanQuery result = new BooleanQuery(coordDisabled);
foreach (BooleanClause booleanClause in allClauses.Keys)
{
result.Add(booleanClause);
}
return result;
}
/// <summary>Expert: Returns the Similarity implementation to be used for this query.
/// Subclasses may override this method to specify their own Similarity
/// implementation, perhaps one that delegates through that of the Searcher.
/// By default the Searcher's Similarity implementation is returned.
/// </summary>
public virtual Similarity GetSimilarity(Searcher searcher)
{
return searcher.GetSimilarity();
}
/// <summary>Returns a clone of this query. </summary>
public virtual System.Object Clone()
{
try
{
return (Query) base.MemberwiseClone();
}
catch (System.Exception e)
{
throw new System.SystemException("Clone not supported: " + e.Message);
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.