/* * 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 { /// The abstract base class for queries. ///

Instantiable subclasses are: ///

///

A parser for queries is contained in: ///

///
[Serializable] public abstract class Query : System.ICloneable { private float boost = 1.0f; // query boost factor /// Sets the boost for this query clause to b. Documents /// matching this clause will (in addition to the normal weightings) have /// their score multiplied by b. /// public virtual void SetBoost(float b) { boost = b; } /// Gets the boost for this clause. Documents matching /// this clause will (in addition to the normal weightings) have their score /// multiplied by b. The boost is 1.0 by default. /// public virtual float GetBoost() { return boost; } /// Prints a query to a string, with field assumed to be the /// default field and omitted. ///

The representation used is one that is supposed to be readable /// by {@link Lucene.Net.QueryParsers.QueryParser QueryParser}. However, /// there are the following limitations: ///

///
public abstract System.String ToString(System.String field); /// Prints a query to a string. public override System.String ToString() { return ToString(""); } /// Expert: Constructs an appropriate Weight implementation for this query. /// ///

/// Only implemented by primitive queries, which re-write to themselves. ///

public virtual Weight CreateWeight(Searcher searcher) { throw new System.NotSupportedException(); } /// Expert: Constructs and initializes a Weight for a top-level query. 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; } /// Expert: called to re-write queries into primitive queries. For example, /// a PrefixQuery will be rewritten into a BooleanQuery that consists /// of TermQuerys. /// public virtual Query Rewrite(IndexReader reader) { return this; } /// 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()). /// 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. /// 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++) { SupportClass.CollectionsHelper.AddIfNotContains(uniques, clauses[j].GetQuery()); } } else { SupportClass.CollectionsHelper.AddIfNotContains(uniques, query); } } // optimization: if we have just one query, just return it if (uniques.Count == 1) { foreach (object key in uniques.Keys) { return (Query) key; } } BooleanQuery result = new BooleanQuery(true); foreach (object key in uniques.Keys) { result.Add((Query) key, BooleanClause.Occur.SHOULD); } return result; } /// Expert: adds all terms occuring in this query to the terms set. Only /// works if this query is in its {@link #rewrite rewritten} form. /// /// /// UnsupportedOperationException if this query is not yet rewritten public virtual void ExtractTerms(System.Collections.Hashtable terms) { // needs to be implemented by query subclasses throw new System.NotSupportedException(); } /// Expert: merges the clauses of a set of BooleanQuery's into a single /// BooleanQuery. /// ///

A utility for use by {@link #Combine(Query[])} implementations. ///

public static Query MergeBooleanQueries(BooleanQuery[] queries) { System.Collections.Hashtable allClauses = new System.Collections.Hashtable(); for (int i = 0; i < queries.Length; i++) { BooleanClause[] clauses = queries[i].GetClauses(); for (int j = 0; j < clauses.Length; j++) { SupportClass.CollectionsHelper.AddIfNotContains(allClauses, clauses[j]); } } bool coordDisabled = queries.Length == 0?false:queries[0].IsCoordDisabled(); BooleanQuery result = new BooleanQuery(coordDisabled); System.Collections.IEnumerator i2 = allClauses.GetEnumerator(); while (i2.MoveNext()) { result.Add((BooleanClause) i2.Current); } return result; } /// 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. /// public virtual Similarity GetSimilarity(Searcher searcher) { return searcher.GetSimilarity(); } /// Returns a clone of this query. public virtual System.Object Clone() { try { return base.MemberwiseClone(); } catch (System.Exception e) { throw new System.SystemException("Clone not supported: " + e.Message); } } public override int GetHashCode() { int prime = 31; int result = 1; result = prime * result + BitConverter.ToInt32(BitConverter.GetBytes(boost), 0); return result; } public override bool Equals(System.Object obj) { if (this == obj) return true; if (obj == null) return false; if (GetType() != obj.GetType()) return false; Query other = (Query) obj; if (BitConverter.ToInt32(BitConverter.GetBytes(boost), 0) != BitConverter.ToInt32(BitConverter.GetBytes(other.boost), 0)) return false; return true; } } }