下面列出了org.apache.lucene.search.BooleanClause#getQuery ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public Query getQuery() throws ParseException
{
BooleanQuery query = booleanQuery.build();
if(query.clauses().size() == 0)
{
return getMatchNoneQuery();
}
else if (query.clauses().size() == 1)
{
BooleanClause clause = query.clauses().get(0);
if(clause.isProhibited())
{
booleanQuery.add(getMatchAllQuery(), Occur.MUST);
return booleanQuery.build();
}
else
{
return clause.getQuery();
}
}
else
{
return query;
}
}
public Query getNegatedQuery() throws ParseException
{
BooleanQuery query = booleanQuery.build();
if(query.clauses().size() == 0)
{
return getMatchAllQuery();
}
else if (query.clauses().size() == 1)
{
BooleanClause clause = query.clauses().get(0);
if(clause.isProhibited())
{
return clause.getQuery();
}
else
{
return Lucene4QueryParserAdaptor.this.getNegatedQuery(getQuery());
}
}
else
{
return Lucene4QueryParserAdaptor.this.getNegatedQuery(getQuery());
}
}
private Query getBoostedQuery(Query mltquery) {
BooleanQuery boostedQuery = (BooleanQuery)mltquery;
if (boostFields.size() > 0) {
BooleanQuery.Builder newQ = new BooleanQuery.Builder();
newQ.setMinimumNumberShouldMatch(boostedQuery.getMinimumNumberShouldMatch());
for (BooleanClause clause : boostedQuery) {
Query q = clause.getQuery();
float originalBoost = 1f;
if (q instanceof BoostQuery) {
BoostQuery bq = (BoostQuery) q;
q = bq.getQuery();
originalBoost = bq.getBoost();
}
Float fieldBoost = boostFields.get(((TermQuery) q).getTerm().field());
q = ((fieldBoost != null) ? new BoostQuery(q, fieldBoost * originalBoost) : clause.getQuery());
newQ.add(q, clause.getOccur());
}
boostedQuery = newQ.build();
}
return boostedQuery;
}
private void fillInterestingTermsFromMLTQuery( Query query, List<InterestingTerm> terms )
{
Collection<BooleanClause> clauses = ((BooleanQuery)query).clauses();
for( BooleanClause o : clauses ) {
Query q = o.getQuery();
float boost = 1f;
if (q instanceof BoostQuery) {
BoostQuery bq = (BoostQuery) q;
q = bq.getQuery();
boost = bq.getBoost();
}
InterestingTerm it = new InterestingTerm();
it.boost = boost;
it.term = ((TermQuery) q).getTerm();
terms.add( it );
}
// alternatively we could use
// mltquery.extractTerms( terms );
}
private static void flattenBooleanQuery(BooleanQuery.Builder to, BooleanQuery from, float fromBoost) {
for (BooleanClause clause : from.clauses()) {
Query cq = clause.getQuery();
float boost = fromBoost;
while (cq instanceof BoostQuery) {
BoostQuery bq = (BoostQuery) cq;
cq = bq.getQuery();
boost *= bq.getBoost();
}
if (cq instanceof BooleanQuery
&& !clause.isRequired()
&& !clause.isProhibited()) {
/* we can recurse */
flattenBooleanQuery(to, (BooleanQuery)cq, boost);
} else {
to.add(clause);
}
}
}
@Override
public Query applyMinimumShouldMatch(final BooleanQuery query) {
final List<BooleanClause> clauses = query.clauses();
if (clauses.size() < 2) {
return query;
}
for (final BooleanClause clause : clauses) {
if ((clause.getQuery() instanceof BooleanQuery) && (clause.getOccur() != BooleanClause.Occur.MUST)) {
return query; // seems to be a complex query with sub queries - do not
// apply mm
}
}
return SolrPluginUtils.setMinShouldMatch(query, minShouldMatch);
}
@Override
public Query handle(Query query, QueryTransformer queryTransformer) {
BooleanQuery booleanQuery = (BooleanQuery) query;
boolean changed = false;
BooleanQuery.Builder builder = new BooleanQuery.Builder();
for (BooleanClause clause: booleanQuery.clauses()) {
Query newClauseQuery = queryTransformer.transform(clause.getQuery());
if (newClauseQuery != clause.getQuery()) {
changed = true;
builder.add(new BooleanClause(newClauseQuery, clause.getOccur()));
} else {
builder.add(clause);
}
}
if (changed) {
builder.setMinimumNumberShouldMatch(booleanQuery.getMinimumNumberShouldMatch());
return builder.build();
}
return query;
}
private static void attach (final BooleanQuery query, final TermCollector collector) {
for (BooleanClause clause : query.getClauses()) {
final Query q = clause.getQuery();
if (!(q instanceof TermCollector.TermCollecting)) {
throw new IllegalArgumentException();
}
((TermCollector.TermCollecting)q).attach(collector);
}
}
public void testBoostFactor() throws Throwable {
Map<String,Float> originalValues = getOriginalValues();
mlt.setFieldNames(new String[] {"text"});
mlt.setBoost(true);
// this mean that every term boost factor will be multiplied by this
// number
float boostFactor = 5;
mlt.setBoostFactor(boostFactor);
BooleanQuery query = (BooleanQuery) mlt.like("text", new StringReader(
"lucene release"));
Collection<BooleanClause> clauses = query.clauses();
assertEquals("Expected " + originalValues.size() + " clauses.",
originalValues.size(), clauses.size());
for (BooleanClause clause : clauses) {
BoostQuery bq = (BoostQuery) clause.getQuery();
TermQuery tq = (TermQuery) bq.getQuery();
Float termBoost = originalValues.get(tq.getTerm().text());
assertNotNull("Expected term " + tq.getTerm().text(), termBoost);
float totalBoost = termBoost * boostFactor;
assertEquals("Expected boost of " + totalBoost + " for term '"
+ tq.getTerm().text() + "' got " + bq.getBoost(), totalBoost, bq
.getBoost(), 0.0001);
}
}
private Map<String,Float> getOriginalValues() throws IOException {
Map<String,Float> originalValues = new HashMap<>();
mlt.setFieldNames(new String[] {"text"});
mlt.setBoost(true);
BooleanQuery query = (BooleanQuery) mlt.like("text", new StringReader(
"lucene release"));
Collection<BooleanClause> clauses = query.clauses();
for (BooleanClause clause : clauses) {
BoostQuery bq = (BoostQuery) clause.getQuery();
TermQuery tq = (TermQuery) bq.getQuery();
originalValues.put(tq.getTerm().text(), bq.getBoost());
}
return originalValues;
}
private void addDebugInfo(ResponseBuilder rb, Elevation elevation) {
List<String> match = null;
if (elevation != null) {
// Extract the elevated terms into a list
match = new ArrayList<>(elevation.includeQuery.clauses().size());
for (BooleanClause clause : elevation.includeQuery.clauses()) {
TermQuery tq = (TermQuery) clause.getQuery();
match.add(tq.getTerm().text());
}
}
SimpleOrderedMap<Object> dbg = new SimpleOrderedMap<>();
dbg.add("q", rb.getQueryString());
dbg.add("match", match);
rb.addDebugInfo("queryBoosting", dbg);
}
/**
* Handle multi-term queries by repacking boolean queries with frequently misspelled term
* queries rewritten as fuzzy queries.
**/
@Override
protected Query newFieldQuery(Analyzer analyzer, String field, String queryText,
boolean quoted, boolean fieldAutoGenPhraseQueries,
boolean fieldEnableGraphQueries, SynonymQueryStyle synonymQueryStyle)
throws SyntaxError {
Query q = super.newFieldQuery
(analyzer, field, queryText, quoted, fieldAutoGenPhraseQueries, fieldEnableGraphQueries, synonymQueryStyle);
if (q instanceof BooleanQuery) {
boolean rewrittenSubQ = false; // dirty flag: rebuild the repacked query?
BooleanQuery.Builder builder = newBooleanQuery();
for (BooleanClause clause : ((BooleanQuery)q).clauses()) {
Query subQ = clause.getQuery();
if (subQ instanceof TermQuery) {
Term subTerm = ((TermQuery)subQ).getTerm();
if (frequentlyMisspelledWords.contains(subTerm.text())) {
rewrittenSubQ = true;
Query fuzzySubQ = newFuzzyQuery(subTerm, MIN_SIMILARITY, getFuzzyPrefixLength());
clause = newBooleanClause(fuzzySubQ, clause.getOccur());
}
}
builder.add(clause);
}
if (rewrittenSubQ) {
builder.setMinimumNumberShouldMatch(((BooleanQuery)q).getMinimumNumberShouldMatch());
q = builder.build();
}
}
return q;
}
private Query boolToExtendedCommonTermsQuery(BooleanQuery bq,
Occur highFreqOccur,
Occur lowFreqOccur,
float maxTermFrequency) {
ExtendedCommonTermsQuery query = new ExtendedCommonTermsQuery(highFreqOccur, lowFreqOccur, maxTermFrequency);
for (BooleanClause clause : bq.clauses()) {
if ((clause.getQuery() instanceof TermQuery) == false) {
return bq;
}
query.add(((TermQuery) clause.getQuery()).getTerm());
}
return query;
}
/**
* Checks the number of optional clauses in the query, and compares it
* with the specification string to determine the proper value to use.
* <p>
* If mmAutoRelax=true, we'll perform auto relaxation of mm if tokens
* are removed from some but not all DisMax clauses, as can happen when
* stopwords or punctuation tokens are removed in analysis.
* </p>
* <p>
* Details about the specification format can be found
* <a href="doc-files/min-should-match.html">here</a>
* </p>
*
* <p>A few important notes...</p>
* <ul>
* <li>
* If the calculations based on the specification determine that no
* optional clauses are needed, BooleanQuerysetMinMumberShouldMatch
* will never be called, but the usual rules about BooleanQueries
* still apply at search time (a BooleanQuery containing no required
* clauses must still match at least one optional clause)
* <li>
* <li>
* No matter what number the calculation arrives at,
* BooleanQuery.setMinShouldMatch() will never be called with a
* value greater then the number of optional clauses (or less then 1)
* </li>
* </ul>
*
* <p>:TODO: should optimize the case where number is same
* as clauses to just make them all "required"
* </p>
*
* @param q The query as a BooleanQuery.Builder
* @param spec The mm spec
* @param mmAutoRelax whether to perform auto relaxation of mm if tokens are removed from some but not all DisMax clauses
*/
public static void setMinShouldMatch(BooleanQuery.Builder q, String spec, boolean mmAutoRelax) {
int optionalClauses = 0;
int maxDisjunctsSize = 0;
int optionalDismaxClauses = 0;
for (BooleanClause c : q.build().clauses()) {
if (c.getOccur() == Occur.SHOULD) {
if (mmAutoRelax && c.getQuery() instanceof DisjunctionMaxQuery) {
int numDisjuncts = ((DisjunctionMaxQuery)c.getQuery()).getDisjuncts().size();
if (numDisjuncts>maxDisjunctsSize) {
maxDisjunctsSize = numDisjuncts;
optionalDismaxClauses = 1;
}
else if (numDisjuncts == maxDisjunctsSize) {
optionalDismaxClauses++;
}
} else {
optionalClauses++;
}
}
}
int msm = calculateMinShouldMatch(optionalClauses + optionalDismaxClauses, spec);
if (0 < msm) {
q.setMinimumNumberShouldMatch(msm);
}
}