📄 booleanquery.cs
字号:
/*
* 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;
using ToStringUtils = Lucene.Net.Util.ToStringUtils;
using Occur = Lucene.Net.Search.BooleanClause.Occur;
namespace Lucene.Net.Search
{
/// <summary>A Query that matches documents matching boolean combinations of other
/// queries, e.g. {@link TermQuery}s, {@link PhraseQuery}s or other
/// BooleanQuerys.
/// </summary>
[Serializable]
public class BooleanQuery : Query, System.ICloneable
{
private class AnonymousClassSimilarityDelegator : SimilarityDelegator
{
private void InitBlock(BooleanQuery enclosingInstance)
{
this.enclosingInstance = enclosingInstance;
}
private BooleanQuery enclosingInstance;
public BooleanQuery Enclosing_Instance
{
get
{
return enclosingInstance;
}
}
internal AnonymousClassSimilarityDelegator(BooleanQuery enclosingInstance, Lucene.Net.Search.Similarity Param1):base(Param1)
{
InitBlock(enclosingInstance);
}
public override float Coord(int overlap, int maxOverlap)
{
return 1.0f;
}
}
private static int maxClauseCount = 1024;
/// <summary>Thrown when an attempt is made to add more than {@link
/// #GetMaxClauseCount()} clauses. This typically happens if
/// a PrefixQuery, FuzzyQuery, WildcardQuery, or RangeQuery
/// is expanded to many terms during search.
/// </summary>
[Serializable]
public class TooManyClauses : System.SystemException
{
public override System.String Message
{
get
{
return "maxClauseCount is set to " + Lucene.Net.Search.BooleanQuery.maxClauseCount;
}
}
public TooManyClauses()
{
}
}
/// <summary>Return the maximum number of clauses permitted, 1024 by default.
/// Attempts to add more than the permitted number of clauses cause {@link
/// TooManyClauses} to be thrown.
/// </summary>
/// <seealso cref="#SetMaxClauseCount(int)">
/// </seealso>
public static int GetMaxClauseCount()
{
return maxClauseCount;
}
/// <summary>Set the maximum number of clauses permitted per BooleanQuery.
/// Default value is 1024.
/// <p>TermQuery clauses are generated from for example prefix queries and
/// fuzzy queries. Each TermQuery needs some buffer space during search,
/// so this parameter indirectly controls the maximum buffer requirements for
/// query search.
/// <p>When this parameter becomes a bottleneck for a Query one can use a
/// Filter. For example instead of a {@link RangeQuery} one can use a
/// {@link RangeFilter}.
/// <p>Normally the buffers are allocated by the JVM. When using for example
/// {@link Lucene.Net.Store.MMapDirectory} the buffering is left to
/// the operating system.
/// </summary>
public static void SetMaxClauseCount(int maxClauseCount)
{
if (maxClauseCount < 1)
throw new System.ArgumentException("maxClauseCount must be >= 1");
BooleanQuery.maxClauseCount = maxClauseCount;
}
private System.Collections.ArrayList clauses = new System.Collections.ArrayList();
private bool disableCoord;
/// <summary>Constructs an empty boolean query. </summary>
public BooleanQuery()
{
}
/// <summary>Constructs an empty boolean query.
///
/// {@link Similarity#Coord(int,int)} may be disabled in scoring, as
/// appropriate. For example, this score factor does not make sense for most
/// automatically generated queries, like {@link WildcardQuery} and {@link
/// FuzzyQuery}.
///
/// </summary>
/// <param name="disableCoord">disables {@link Similarity#Coord(int,int)} in scoring.
/// </param>
public BooleanQuery(bool disableCoord)
{
this.disableCoord = disableCoord;
}
/// <summary>Returns true iff {@link Similarity#Coord(int,int)} is disabled in
/// scoring for this query instance.
/// </summary>
/// <seealso cref="#BooleanQuery(boolean)">
/// </seealso>
public virtual bool IsCoordDisabled()
{
return disableCoord;
}
// Implement coord disabling.
// Inherit javadoc.
public override Similarity GetSimilarity(Searcher searcher)
{
Similarity result = base.GetSimilarity(searcher);
if (disableCoord)
{
// disable coord as requested
result = new AnonymousClassSimilarityDelegator(this, result);
}
return result;
}
/// <summary> Specifies a minimum number of the optional BooleanClauses
/// which must be satisifed.
///
/// <p>
/// By default no optional clauses are neccessary for a match
/// (unless there are no required clauses). If this method is used,
/// then the specified numebr of clauses is required.
/// </p>
/// <p>
/// Use of this method is totally independant of specifying that
/// any specific clauses are required (or prohibited). This number will
/// only be compared against the number of matching optional clauses.
/// </p>
/// <p>
/// EXPERT NOTE: Using this method will force the use of BooleanWeight2,
/// regardless of wether setUseScorer14(true) has been called.
/// </p>
///
/// </summary>
/// <param name="min">the number of optional clauses that must match
/// </param>
/// <seealso cref="#setUseScorer14">
/// </seealso>
public virtual void SetMinimumNumberShouldMatch(int min)
{
this.minNrShouldMatch = min;
}
protected internal int minNrShouldMatch = 0;
/// <summary> Gets the minimum number of the optional BooleanClauses
/// which must be satisifed.
/// </summary>
public virtual int GetMinimumNumberShouldMatch()
{
return minNrShouldMatch;
}
/// <summary>Adds a clause to a boolean query.
///
/// </summary>
/// <throws> TooManyClauses if the new number of clauses exceeds the maximum clause number </throws>
/// <seealso cref="#GetMaxClauseCount()">
/// </seealso>
public virtual void Add(Query query, BooleanClause.Occur occur)
{
Add(new BooleanClause(query, occur));
}
/// <summary>Adds a clause to a boolean query.</summary>
/// <throws> TooManyClauses if the new number of clauses exceeds the maximum clause number </throws>
/// <seealso cref="#GetMaxClauseCount()">
/// </seealso>
public virtual void Add(BooleanClause clause)
{
if (clauses.Count >= maxClauseCount)
throw new TooManyClauses();
clauses.Add(clause);
}
/// <summary>Returns the set of clauses in this query. </summary>
public virtual BooleanClause[] GetClauses()
{
return (BooleanClause[]) clauses.ToArray(typeof(BooleanClause));
}
/// <summary>Returns the list of clauses in this query. </summary>
public virtual System.Collections.IList Clauses()
{
return clauses;
}
[Serializable]
private class BooleanWeight : Weight
{
private void InitBlock(BooleanQuery enclosingInstance)
{
this.enclosingInstance = enclosingInstance;
}
private BooleanQuery enclosingInstance;
public BooleanQuery Enclosing_Instance
{
get
{
return enclosingInstance;
}
}
protected internal Similarity similarity;
protected internal System.Collections.ArrayList weights = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
public BooleanWeight(BooleanQuery enclosingInstance, Searcher searcher)
{
InitBlock(enclosingInstance);
this.similarity = Enclosing_Instance.GetSimilarity(searcher);
for (int i = 0; i < Enclosing_Instance.clauses.Count; i++)
{
BooleanClause c = (BooleanClause) Enclosing_Instance.clauses[i];
weights.Add(c.GetQuery().CreateWeight(searcher));
}
}
public virtual Query GetQuery()
{
return Enclosing_Instance;
}
public virtual float GetValue()
{
return Enclosing_Instance.GetBoost();
}
public virtual float SumOfSquaredWeights()
{
float sum = 0.0f;
for (int i = 0; i < weights.Count; i++)
{
BooleanClause c = (BooleanClause) Enclosing_Instance.clauses[i];
Weight w = (Weight) weights[i];
// call sumOfSquaredWeights for all clauses in case of side effects
float s = w.SumOfSquaredWeights(); // sum sub k
if (!c.IsProhibited())
// only add to sum for non-prohibited clauses
sum += s;
}
sum *= Enclosing_Instance.GetBoost() * Enclosing_Instance.GetBoost(); // boost each sub-weight
return sum;
}
public virtual void Normalize(float norm)
{
norm *= Enclosing_Instance.GetBoost(); // incorporate boost
for (int i = 0; i < weights.Count; i++)
{
BooleanClause c = (BooleanClause) Enclosing_Instance.clauses[i];
Weight w = (Weight) weights[i];
// normalize all clauses, (even if prohibited in case of side affects)
w.Normalize(norm);
}
}
/// <returns> A good old 1.4 Scorer
/// </returns>
public virtual Scorer Scorer(IndexReader reader)
{
// First see if the (faster) ConjunctionScorer will work. This can be
// used when all clauses are required. Also, at this point a
// BooleanScorer cannot be embedded in a ConjunctionScorer, as the hits
// from a BooleanScorer are not always sorted by document number (sigh)
// and hence BooleanScorer cannot implement skipTo() correctly, which is
// required by ConjunctionScorer.
bool allRequired = true;
bool noneBoolean = true;
for (int i = 0; i < weights.Count; i++)
{
BooleanClause c = (BooleanClause) Enclosing_Instance.clauses[i];
if (!c.IsRequired())
allRequired = false;
if (c.GetQuery() is BooleanQuery)
noneBoolean = false;
}
if (allRequired && noneBoolean)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -