下面列出了org.apache.lucene.search.BooleanClause#getOccur ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private BooleanClause.Occur resolveClauseOccur(BooleanClause clause) {
BooleanClause.Occur occur = clause.getOccur();
if (negate) {
switch (occur) {
case SHOULD:
occur = BooleanClause.Occur.MUST_NOT;
break;
case MUST:
occur = BooleanClause.Occur.SHOULD;
break;
case MUST_NOT:
occur = BooleanClause.Occur.SHOULD;
break;
}
}
return occur;
}
private Collection<Pipe> processOrClauses(Map<BooleanClause.Occur, Collection<BooleanClause>> groupedClauses) {
Collection<BooleanClause> shouldClauses = groupedClauses.get(BooleanClause.Occur.SHOULD);
Collection<Pipe> orPipes = new ArrayList<>();
if (shouldClauses != null) {
for (BooleanClause shouldClause : shouldClauses) {
QueryExpression queryExpression = queryFactory.create(shouldClause.getQuery(), resourceDefinition);
// don't negate expression if we negated MUST_NOT -> SHOULD
if (negate && shouldClause.getOccur() != BooleanClause.Occur.MUST_NOT) {
queryExpression.setNegate();
}
properties.addAll(queryExpression.getProperties());
orPipes.add(queryExpression.asPipe());
}
}
return orPipes;
}
@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);
}
protected QueryBuilder convertBooleanQuery(final QueryContext context, final BooleanQuery booleanQuery, final float boost) {
final BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
for (final BooleanClause clause : booleanQuery.clauses()) {
final QueryBuilder queryBuilder = convertQuery(context, clause.getQuery(), boost);
if (queryBuilder != null) {
switch (clause.getOccur()) {
case MUST:
boolQuery.must(queryBuilder);
break;
case SHOULD:
boolQuery.should(queryBuilder);
break;
case MUST_NOT:
boolQuery.mustNot(queryBuilder);
break;
default:
break;
}
}
}
if (boolQuery.hasClauses()) {
return boolQuery;
}
return null;
}
public static Query applyMinimumShouldMatch(BooleanQuery query, @Nullable String minimumShouldMatch) {
if (minimumShouldMatch == null) {
return query;
}
int optionalClauses = 0;
for (BooleanClause c : query.clauses()) {
if (c.getOccur() == BooleanClause.Occur.SHOULD) {
optionalClauses++;
}
}
int msm = calculateMinShouldMatch(optionalClauses, minimumShouldMatch);
if (0 < msm) {
BooleanQuery.Builder builder = new BooleanQuery.Builder();
for (BooleanClause clause : query) {
builder.add(clause);
}
builder.setMinimumNumberShouldMatch(msm);
return builder.build();
} else {
return query;
}
}
private boolean containsAllNegativeQueries(BooleanQuery booleanQuery) {
for (BooleanClause clause : booleanQuery.clauses()) {
if (clause.getOccur() == Occur.MUST || clause.getOccur() == Occur.SHOULD) {
return false;
}
}
return true;
}
/**
* Decompose a {@link org.apache.lucene.search.BooleanQuery}
*
* @param q the boolean query
* @return a collection of subqueries
*/
public Set<Query> decomposeBoolean(BooleanQuery q) {
if (q.getMinimumNumberShouldMatch() > 1)
return Collections.singleton(q);
Set<Query> subqueries = new HashSet<>();
Set<Query> exclusions = new HashSet<>();
Set<Query> mandatory = new HashSet<>();
for (BooleanClause clause : q) {
if (clause.getOccur() == BooleanClause.Occur.MUST || clause.getOccur() == BooleanClause.Occur.FILTER)
mandatory.add(clause.getQuery());
else if (clause.getOccur() == BooleanClause.Occur.MUST_NOT)
exclusions.add(clause.getQuery());
else {
subqueries.addAll(decompose(clause.getQuery()));
}
}
// More than one MUST clause, or a single MUST clause with disjunctions
if (mandatory.size() > 1 || (mandatory.size() == 1 && subqueries.size() > 0))
return Collections.singleton(q);
// If we only have a single MUST clause and no SHOULD clauses, then we can
// decompose the MUST clause instead
if (mandatory.size() == 1) {
subqueries.addAll(decompose(mandatory.iterator().next()));
}
if (exclusions.size() == 0)
return subqueries;
// If there are exclusions, then we need to add them to all the decomposed
// queries
Set<Query> rewrittenSubqueries = new HashSet<>(subqueries.size());
for (Query subquery : subqueries) {
BooleanQuery.Builder bq = new BooleanQuery.Builder();
bq.add(subquery, BooleanClause.Occur.MUST);
for (Query ex : exclusions) {
bq.add(ex, BooleanClause.Occur.MUST_NOT);
}
rewrittenSubqueries.add(bq.build());
}
return rewrittenSubqueries;
}
/**
* 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);
}
}