multi_match query supports fields as single string and array
The multi_match query accepted only an array in the fields parameter. This patch allows to use a single string as well. Also added tests for parsing in both cases. Closes #4164
This commit is contained in:
parent
826b8bd742
commit
c8020760d7
|
@ -67,33 +67,13 @@ public class MultiMatchQueryParser implements QueryParser {
|
|||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
if ("fields".equals(currentFieldName)) {
|
||||
} else if ("fields".equals(currentFieldName)) {
|
||||
if (token == XContentParser.Token.START_ARRAY) {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
String fField = null;
|
||||
Float fBoost = null;
|
||||
char[] fieldText = parser.textCharacters();
|
||||
int end = parser.textOffset() + parser.textLength();
|
||||
for (int i = parser.textOffset(); i < end; i++) {
|
||||
if (fieldText[i] == '^') {
|
||||
int relativeLocation = i - parser.textOffset();
|
||||
fField = new String(fieldText, parser.textOffset(), relativeLocation);
|
||||
fBoost = Float.parseFloat(new String(fieldText, i + 1, parser.textLength() - relativeLocation - 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fField == null) {
|
||||
fField = parser.text();
|
||||
}
|
||||
|
||||
if (Regex.isSimpleMatchPattern(fField)) {
|
||||
for (String field : parseContext.mapperService().simpleMatchToIndexNames(fField)) {
|
||||
fieldNameWithBoosts.put(field, fBoost);
|
||||
}
|
||||
} else {
|
||||
fieldNameWithBoosts.put(fField, fBoost);
|
||||
}
|
||||
extractFieldAndBoost(parseContext, parser, fieldNameWithBoosts);
|
||||
}
|
||||
} else if (token.isValue()) {
|
||||
extractFieldAndBoost(parseContext, parser, fieldNameWithBoosts);
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "[query_string] query does not support [" + currentFieldName + "]");
|
||||
}
|
||||
|
@ -184,4 +164,30 @@ public class MultiMatchQueryParser implements QueryParser {
|
|||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
private void extractFieldAndBoost(QueryParseContext parseContext, XContentParser parser, Map<String, Float> fieldNameWithBoosts) throws IOException {
|
||||
String fField = null;
|
||||
Float fBoost = null;
|
||||
char[] fieldText = parser.textCharacters();
|
||||
int end = parser.textOffset() + parser.textLength();
|
||||
for (int i = parser.textOffset(); i < end; i++) {
|
||||
if (fieldText[i] == '^') {
|
||||
int relativeLocation = i - parser.textOffset();
|
||||
fField = new String(fieldText, parser.textOffset(), relativeLocation);
|
||||
fBoost = Float.parseFloat(new String(fieldText, i + 1, parser.textLength() - relativeLocation - 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fField == null) {
|
||||
fField = parser.text();
|
||||
}
|
||||
|
||||
if (Regex.isSimpleMatchPattern(fField)) {
|
||||
for (String field : parseContext.mapperService().simpleMatchToIndexNames(fField)) {
|
||||
fieldNameWithBoosts.put(field, fBoost);
|
||||
}
|
||||
} else {
|
||||
fieldNameWithBoosts.put(fField, fBoost);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2268,4 +2268,20 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
|
|||
Query parsedQuery = queryParser.parse(query).query();
|
||||
assertThat((double) (parsedQuery.getBoost()), Matchers.closeTo(3.0, 1.e-7));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiMatchQuery() throws Exception {
|
||||
IndexQueryParserService queryParser = queryParser();
|
||||
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/multiMatch-query-simple.json");
|
||||
Query parsedQuery = queryParser.parse(query).query();
|
||||
assertThat(parsedQuery, instanceOf(DisjunctionMaxQuery.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiMatchQueryWithFieldsAsString() throws Exception {
|
||||
IndexQueryParserService queryParser = queryParser();
|
||||
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/multiMatch-query-fields-as-string.json");
|
||||
Query parsedQuery = queryParser.parse(query).query();
|
||||
assertThat(parsedQuery, instanceOf(BooleanQuery.class));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"multi_match": {
|
||||
"query": "foo bar",
|
||||
"fields": "myField"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"multi_match": {
|
||||
"query": "foo bar",
|
||||
"fields": [ "myField", "otherField" ]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue