Make BoolFilterBuilder output proper json

This commit is contained in:
tristanbuckner 2013-03-01 15:24:36 -08:00 committed by Shay Banon
parent ea097afd91
commit 9273d76cdf
1 changed files with 47 additions and 40 deletions

View File

@ -21,9 +21,13 @@ package org.elasticsearch.index.query;
import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanClause;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.ToXContent.Params;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* A filter that matches documents matching boolean combinations of other filters. * A filter that matches documents matching boolean combinations of other filters.
@ -32,7 +36,11 @@ import java.util.ArrayList;
*/ */
public class BoolFilterBuilder extends BaseFilterBuilder { public class BoolFilterBuilder extends BaseFilterBuilder {
private ArrayList<Clause> clauses = new ArrayList<Clause>(); private ArrayList<FilterBuilder> mustClauses = new ArrayList<FilterBuilder>();
private ArrayList<FilterBuilder> mustNotClauses = new ArrayList<FilterBuilder>();
private ArrayList<FilterBuilder> shouldClauses = new ArrayList<FilterBuilder>();
private Boolean cache; private Boolean cache;
private String cacheKey; private String cacheKey;
@ -43,7 +51,7 @@ public class BoolFilterBuilder extends BaseFilterBuilder {
* Adds a filter that <b>must</b> appear in the matching documents. * Adds a filter that <b>must</b> appear in the matching documents.
*/ */
public BoolFilterBuilder must(FilterBuilder filterBuilder) { public BoolFilterBuilder must(FilterBuilder filterBuilder) {
clauses.add(new Clause(filterBuilder, BooleanClause.Occur.MUST)); mustClauses.add(filterBuilder);
return this; return this;
} }
@ -51,17 +59,18 @@ public class BoolFilterBuilder extends BaseFilterBuilder {
* Adds a filter that <b>must not</b> appear in the matching documents. * Adds a filter that <b>must not</b> appear in the matching documents.
*/ */
public BoolFilterBuilder mustNot(FilterBuilder filterBuilder) { public BoolFilterBuilder mustNot(FilterBuilder filterBuilder) {
clauses.add(new Clause(filterBuilder, BooleanClause.Occur.MUST_NOT)); mustNotClauses.add(filterBuilder);
return this; return this;
} }
/** /**
* Adds multiple <i>should</i> filters. * Adds a filter that <i>should</i> appear in the matching documents. For a boolean filter
* with no <tt>MUST</tt> clauses one or more <code>SHOULD</code> clauses must match a document
* for the BooleanQuery to match.
*/ */
public BoolFilterBuilder should(FilterBuilder... filterBuilders) { public BoolFilterBuilder should(FilterBuilder filterBuilder) {
for (FilterBuilder filterBuilder : filterBuilders) { shouldClauses.add(filterBuilder);
clauses.add(new Clause(filterBuilder, BooleanClause.Occur.SHOULD));
}
return this; return this;
} }
@ -69,8 +78,8 @@ public class BoolFilterBuilder extends BaseFilterBuilder {
* Adds multiple <i>must</i> filters. * Adds multiple <i>must</i> filters.
*/ */
public BoolFilterBuilder must(FilterBuilder... filterBuilders) { public BoolFilterBuilder must(FilterBuilder... filterBuilders) {
for (FilterBuilder filterBuilder : filterBuilders) { for (FilterBuilder fb : filterBuilders) {
clauses.add(new Clause(filterBuilder, BooleanClause.Occur.MUST)); mustClauses.add(fb);
} }
return this; return this;
} }
@ -79,19 +88,19 @@ public class BoolFilterBuilder extends BaseFilterBuilder {
* Adds multiple <i>must not</i> filters. * Adds multiple <i>must not</i> filters.
*/ */
public BoolFilterBuilder mustNot(FilterBuilder... filterBuilders) { public BoolFilterBuilder mustNot(FilterBuilder... filterBuilders) {
for (FilterBuilder filterBuilder : filterBuilders) { for (FilterBuilder fb : filterBuilders) {
clauses.add(new Clause(filterBuilder, BooleanClause.Occur.MUST_NOT)); mustNotClauses.add(fb);
} }
return this; return this;
} }
/** /**
* Adds a filter that <i>should</i> appear in the matching documents. For a boolean filter * Adds multiple <i>should</i> filters.
* with no <tt>MUST</tt> clauses one or more <code>SHOULD</code> clauses must match a document
* for the BooleanQuery to match.
*/ */
public BoolFilterBuilder should(FilterBuilder filterBuilder) { public BoolFilterBuilder should(FilterBuilder... filterBuilders) {
clauses.add(new Clause(filterBuilder, BooleanClause.Occur.SHOULD)); for (FilterBuilder fb : filterBuilders) {
shouldClauses.add(fb);
}
return this; return this;
} }
@ -119,18 +128,10 @@ public class BoolFilterBuilder extends BaseFilterBuilder {
@Override @Override
protected void doXContent(XContentBuilder builder, Params params) throws IOException { protected void doXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject("bool"); builder.startObject("bool");
for (Clause clause : clauses) { doXArrayContent("must", mustClauses, builder, params);
if (clause.occur == BooleanClause.Occur.MUST) { doXArrayContent("must_not", mustNotClauses, builder, params);
builder.field("must"); doXArrayContent("should", shouldClauses, builder, params);
clause.filterBuilder.toXContent(builder, params);
} else if (clause.occur == BooleanClause.Occur.MUST_NOT) {
builder.field("must_not");
clause.filterBuilder.toXContent(builder, params);
} else if (clause.occur == BooleanClause.Occur.SHOULD) {
builder.field("should");
clause.filterBuilder.toXContent(builder, params);
}
}
if (filterName != null) { if (filterName != null) {
builder.field("_name", filterName); builder.field("_name", filterName);
} }
@ -143,13 +144,19 @@ public class BoolFilterBuilder extends BaseFilterBuilder {
builder.endObject(); builder.endObject();
} }
private static class Clause { private void doXArrayContent(String field, List<FilterBuilder> clauses, XContentBuilder builder, Params params) throws IOException {
final FilterBuilder filterBuilder; if (clauses.isEmpty()) {
final BooleanClause.Occur occur; return;
}
private Clause(FilterBuilder filterBuilder, BooleanClause.Occur occur) { if (clauses.size() == 1) {
this.filterBuilder = filterBuilder; builder.field(field);
this.occur = occur; clauses.get(0).toXContent(builder, params);
} else {
builder.startArray(field);
for (FilterBuilder clause : clauses) {
clause.toXContent(builder, params);
}
builder.endArray();
} }
} }
} }