Adds a JSONQueryBuilder which allows using a JSON query string through the Java builder API.
This commit is contained in:
parent
1033249f0c
commit
b627ba06c6
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elastic Search and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. Elastic Search 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.index.query;
|
||||||
|
/**
|
||||||
|
* Created by IntelliJ IDEA.
|
||||||
|
* User: cedric
|
||||||
|
* Date: 12/07/11
|
||||||
|
* Time: 11:30
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.apache.lucene.util.UnicodeUtil;
|
||||||
|
import org.elasticsearch.common.jackson.JsonParser;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
|
import org.elasticsearch.common.xcontent.json.JsonXContentParser;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Query builder which allows building a query thanks to a JSON string. This is useful when you want
|
||||||
|
* to use the Java Builder API but still have JSON query strings at hand that you want to combine with other
|
||||||
|
* query builders.
|
||||||
|
*
|
||||||
|
* Example usage in a boolean query :
|
||||||
|
* <pre>
|
||||||
|
* {@code
|
||||||
|
* BoolQueryBuilder bool = new BoolQueryBuilder();
|
||||||
|
* bool.must(new JSONQueryBuilder("{\"term\": {\"field\":\"value\"}}");
|
||||||
|
* bool.must(new TermQueryBuilder("field2","value2");
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author Cedric Champeau
|
||||||
|
*/
|
||||||
|
public class JSONQueryBuilder extends BaseQueryBuilder {
|
||||||
|
|
||||||
|
private final String jsonQuery;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a JSONQueryBuilder using the provided JSON query string.
|
||||||
|
* @param jsonQuery
|
||||||
|
*/
|
||||||
|
public JSONQueryBuilder(String jsonQuery) {
|
||||||
|
this.jsonQuery = jsonQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override protected void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
builder.startObject(JSONQueryParser.NAME);
|
||||||
|
XContentParser parser = JsonXContent.jsonXContent.createParser(jsonQuery);
|
||||||
|
parser.nextToken();
|
||||||
|
builder.field("value");
|
||||||
|
builder.copyCurrentStructure(parser);
|
||||||
|
builder.endObject();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elastic Search and Shay Banon under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. Elastic Search 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
|
import org.apache.lucene.search.Query;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query parser for JSON Queries.
|
||||||
|
*
|
||||||
|
* @author Cedric Champeau
|
||||||
|
*/
|
||||||
|
public class JSONQueryParser implements QueryParser {
|
||||||
|
|
||||||
|
public static final String NAME = "json";
|
||||||
|
|
||||||
|
@Inject public JSONQueryParser() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public String[] names() {
|
||||||
|
return new String[] {NAME};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
|
||||||
|
System.out.println("parseContext = " + parseContext);
|
||||||
|
XContentParser parser = parseContext.parser();
|
||||||
|
XContentParser.Token token;
|
||||||
|
Query query = null;
|
||||||
|
String currentFieldName = null;
|
||||||
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
|
currentFieldName = parser.currentName();
|
||||||
|
} else if (token == XContentParser.Token.START_OBJECT && "value".equals(currentFieldName)) {
|
||||||
|
query = parseContext.parseInnerQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
}
|
|
@ -611,6 +611,10 @@ public abstract class QueryBuilders {
|
||||||
return new PrefixFilterBuilder(name, prefix);
|
return new PrefixFilterBuilder(name, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JSONQueryBuilder json(String jsonString) {
|
||||||
|
return new JSONQueryBuilder(jsonString);
|
||||||
|
}
|
||||||
|
|
||||||
private QueryBuilders() {
|
private QueryBuilders() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ public class IndicesQueriesRegistry {
|
||||||
addQueryParser(queryParsers, new MoreLikeThisFieldQueryParser());
|
addQueryParser(queryParsers, new MoreLikeThisFieldQueryParser());
|
||||||
addQueryParser(queryParsers, new FuzzyLikeThisQueryParser());
|
addQueryParser(queryParsers, new FuzzyLikeThisQueryParser());
|
||||||
addQueryParser(queryParsers, new FuzzyLikeThisFieldQueryParser());
|
addQueryParser(queryParsers, new FuzzyLikeThisFieldQueryParser());
|
||||||
|
addQueryParser(queryParsers, new JSONQueryParser());
|
||||||
this.queryParsers = ImmutableMap.copyOf(queryParsers);
|
this.queryParsers = ImmutableMap.copyOf(queryParsers);
|
||||||
|
|
||||||
Map<String, FilterParser> filterParsers = Maps.newHashMap();
|
Map<String, FilterParser> filterParsers = Maps.newHashMap();
|
||||||
|
|
|
@ -22,6 +22,9 @@ package org.elasticsearch.test.integration.search.query;
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||||
|
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||||
|
import org.elasticsearch.index.query.JSONQueryBuilder;
|
||||||
|
import org.elasticsearch.index.query.TermQueryBuilder;
|
||||||
import org.elasticsearch.test.integration.AbstractNodesTests;
|
import org.elasticsearch.test.integration.AbstractNodesTests;
|
||||||
import org.testng.annotations.AfterClass;
|
import org.testng.annotations.AfterClass;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
|
@ -276,4 +279,29 @@ public class SimpleQueryTests extends AbstractNodesTests {
|
||||||
assertThat(searchResponse.hits().getAt(0).id(), anyOf(equalTo("3"), equalTo("4")));
|
assertThat(searchResponse.hits().getAt(0).id(), anyOf(equalTo("3"), equalTo("4")));
|
||||||
assertThat(searchResponse.hits().getAt(1).id(), anyOf(equalTo("3"), equalTo("4")));
|
assertThat(searchResponse.hits().getAt(1).id(), anyOf(equalTo("3"), equalTo("4")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test public void passQueryAsJSONStringTest() throws Exception {
|
||||||
|
try {
|
||||||
|
client.admin().indices().prepareDelete("test").execute().actionGet();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
client.admin().indices().prepareCreate("test").setSettings(ImmutableSettings.settingsBuilder().put("number_of_shards", 1)).execute().actionGet();
|
||||||
|
|
||||||
|
client.prepareIndex("test", "type1", "1").setSource("field1", "value1_1", "field2", "value2_1").setRefresh(true).execute().actionGet();
|
||||||
|
|
||||||
|
JSONQueryBuilder json = new JSONQueryBuilder("{ \"term\" : { \"field1\" : \"value1_1\" } }");
|
||||||
|
SearchResponse searchResponse = client.prepareSearch().setQuery(json).execute().actionGet();
|
||||||
|
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
|
||||||
|
|
||||||
|
BoolQueryBuilder bool = new BoolQueryBuilder();
|
||||||
|
bool.must(json);
|
||||||
|
bool.must(new TermQueryBuilder("field2", "value2_1"));
|
||||||
|
|
||||||
|
searchResponse = client.prepareSearch().setQuery(json).execute().actionGet();
|
||||||
|
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue