Query DSL: query_string syntax to support wildcard fieldnames in the query text, closes #1936.

This commit is contained in:
Shay Banon 2012-05-10 13:49:18 +03:00
parent c6b593595d
commit cda633afee
7 changed files with 358 additions and 407 deletions

View File

@ -24,12 +24,11 @@ import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.*;
import org.elasticsearch.common.io.FastStringReader;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.internal.AllFieldMapper;
@ -38,6 +37,7 @@ import org.elasticsearch.index.query.QueryParseContext;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static org.elasticsearch.common.lucene.search.Queries.fixNegativeQueryIfNeeded;
@ -64,6 +64,8 @@ public class MapperQueryParser extends QueryParser {
private final QueryParseContext parseContext;
private QueryParserSettings settings;
private Analyzer quoteAnalyzer;
private boolean forcedAnalyzer;
@ -75,8 +77,6 @@ public class MapperQueryParser extends QueryParser {
private String quoteFieldSuffix;
private boolean lenient;
public MapperQueryParser(QueryParseContext parseContext) {
super(Lucene.QUERYPARSER_VERSION, null, null);
this.parseContext = parseContext;
@ -89,7 +89,19 @@ public class MapperQueryParser extends QueryParser {
}
public void reset(QueryParserSettings settings) {
this.settings = settings;
this.field = settings.defaultField();
if (settings.fields() != null) {
if (settings.fields.size() == 1) {
// just mark it as the default field
this.field = settings.fields().get(0);
} else {
// otherwise, we need to have the default field being null...
this.field = null;
}
}
this.forcedAnalyzer = settings.forcedAnalyzer() != null;
this.analyzer = forcedAnalyzer ? settings.forcedAnalyzer() : settings.defaultAnalyzer();
if (settings.forcedQuoteAnalyzer() != null) {
@ -137,6 +149,45 @@ public class MapperQueryParser extends QueryParser {
if (fieldQueryExtension != null) {
return fieldQueryExtension.query(parseContext, queryText);
}
Collection<String> fields = extractMultiFields(field);
if (fields != null) {
if (fields.size() == 1) {
return getFieldQuerySingle(fields.iterator().next(), queryText, quoted);
}
if (settings.useDisMax()) {
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker());
boolean added = false;
for (String mField : fields) {
Query q = getFieldQuerySingle(mField, queryText, quoted);
if (q != null) {
added = true;
applyBoost(mField, q);
disMaxQuery.add(q);
}
}
if (!added) {
return null;
}
return disMaxQuery;
} else {
List<BooleanClause> clauses = new ArrayList<BooleanClause>();
for (String mField : fields) {
Query q = getFieldQuerySingle(mField, queryText, true);
if (q != null) {
applyBoost(mField, q);
clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD));
}
}
if (clauses.size() == 0) // happens for stopwords
return null;
return getBooleanQuery(clauses, true);
}
} else {
return getFieldQuerySingle(field, queryText, quoted);
}
}
private Query getFieldQuerySingle(String field, String queryText, boolean quoted) throws ParseException {
currentMapper = null;
Analyzer oldAnalyzer = analyzer;
try {
@ -176,7 +227,7 @@ public class MapperQueryParser extends QueryParser {
query = currentMapper.fieldQuery(queryText, parseContext);
}
} catch (RuntimeException e) {
if (lenient) {
if (settings.lenient()) {
return null;
} else {
throw e;
@ -195,6 +246,45 @@ public class MapperQueryParser extends QueryParser {
}
}
@Override
protected Query getFieldQuery(String field, String queryText, int slop) throws ParseException {
Collection<String> fields = extractMultiFields(field);
if (fields != null) {
if (settings.useDisMax()) {
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker());
boolean added = false;
for (String mField : fields) {
Query q = super.getFieldQuery(mField, queryText, slop);
if (q != null) {
added = true;
applyBoost(field, q);
applySlop(q, slop);
disMaxQuery.add(q);
}
}
if (!added) {
return null;
}
return disMaxQuery;
} else {
List<BooleanClause> clauses = new ArrayList<BooleanClause>();
for (String mField : fields) {
Query q = super.getFieldQuery(mField, queryText, slop);
if (q != null) {
applyBoost(field, q);
applySlop(q, slop);
clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD));
}
}
if (clauses.size() == 0) // happens for stopwords
return null;
return getBooleanQuery(clauses, true);
}
} else {
return super.getFieldQuery(field, queryText, slop);
}
}
@Override
protected Query getRangeQuery(String field, String part1, String part2, boolean inclusive) throws ParseException {
if ("*".equals(part1)) {
@ -203,13 +293,59 @@ public class MapperQueryParser extends QueryParser {
if ("*".equals(part2)) {
part2 = null;
}
Collection<String> fields = extractMultiFields(field);
if (fields != null) {
if (fields.size() == 1) {
return getRangeQuerySingle(fields.iterator().next(), part1, part2, inclusive);
}
if (settings.useDisMax()) {
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker());
boolean added = false;
for (String mField : fields) {
Query q = getRangeQuerySingle(mField, part1, part2, inclusive);
if (q != null) {
added = true;
applyBoost(mField, q);
disMaxQuery.add(q);
}
}
if (!added) {
return null;
}
return disMaxQuery;
} else {
List<BooleanClause> clauses = new ArrayList<BooleanClause>();
for (String mField : fields) {
Query q = getRangeQuerySingle(mField, part1, part2, inclusive);
if (q != null) {
applyBoost(mField, q);
clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD));
}
}
if (clauses.size() == 0) // happens for stopwords
return null;
return getBooleanQuery(clauses, true);
}
} else {
return getRangeQuerySingle(field, part1, part2, inclusive);
}
}
private Query getRangeQuerySingle(String field, String part1, String part2, boolean inclusive) {
currentMapper = null;
MapperService.SmartNameFieldMappers fieldMappers = parseContext.smartFieldMappers(field);
if (fieldMappers != null) {
currentMapper = fieldMappers.fieldMappers().mapper();
if (currentMapper != null) {
try {
Query rangeQuery = currentMapper.rangeQuery(part1, part2, inclusive, inclusive, parseContext);
return wrapSmartNameQuery(rangeQuery, fieldMappers, parseContext);
} catch (RuntimeException e) {
if (settings.lenient()) {
return null;
}
throw e;
}
}
}
return newRangeQuery(field, part1, part2, inclusive);
@ -217,13 +353,55 @@ public class MapperQueryParser extends QueryParser {
@Override
protected Query getFuzzyQuery(String field, String termStr, float minSimilarity) throws ParseException {
Collection<String> fields = extractMultiFields(field);
if (fields != null) {
if (fields.size() == 1) {
return getFuzzyQuerySingle(fields.iterator().next(), termStr, minSimilarity);
}
if (settings.useDisMax()) {
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker());
boolean added = false;
for (String mField : fields) {
Query q = getFuzzyQuerySingle(mField, termStr, minSimilarity);
if (q != null) {
added = true;
applyBoost(mField, q);
disMaxQuery.add(q);
}
}
if (!added) {
return null;
}
return disMaxQuery;
} else {
List<BooleanClause> clauses = new ArrayList<BooleanClause>();
for (String mField : fields) {
Query q = getFuzzyQuerySingle(mField, termStr, minSimilarity);
applyBoost(mField, q);
clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD));
}
return getBooleanQuery(clauses, true);
}
} else {
return getFuzzyQuerySingle(field, termStr, minSimilarity);
}
}
private Query getFuzzyQuerySingle(String field, String termStr, float minSimilarity) throws ParseException {
currentMapper = null;
MapperService.SmartNameFieldMappers fieldMappers = parseContext.smartFieldMappers(field);
if (fieldMappers != null) {
currentMapper = fieldMappers.fieldMappers().mapper();
if (currentMapper != null) {
try {
Query fuzzyQuery = currentMapper.fuzzyQuery(termStr, minSimilarity, fuzzyPrefixLength, FuzzyQuery.defaultMaxExpansions);
return wrapSmartNameQuery(fuzzyQuery, fieldMappers, parseContext);
} catch (RuntimeException e) {
if (settings.lenient()) {
return null;
}
throw e;
}
}
}
return super.getFuzzyQuery(field, termStr, minSimilarity);
@ -231,6 +409,45 @@ public class MapperQueryParser extends QueryParser {
@Override
protected Query getPrefixQuery(String field, String termStr) throws ParseException {
Collection<String> fields = extractMultiFields(field);
if (fields != null) {
if (fields.size() == 1) {
return getPrefixQuerySingle(fields.iterator().next(), termStr);
}
if (settings.useDisMax()) {
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker());
boolean added = false;
for (String mField : fields) {
Query q = getPrefixQuerySingle(mField, termStr);
if (q != null) {
added = true;
applyBoost(mField, q);
disMaxQuery.add(q);
}
}
if (!added) {
return null;
}
return disMaxQuery;
} else {
List<BooleanClause> clauses = new ArrayList<BooleanClause>();
for (String mField : fields) {
Query q = getPrefixQuerySingle(mField, termStr);
if (q != null) {
applyBoost(mField, q);
clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD));
}
}
if (clauses.size() == 0) // happens for stopwords
return null;
return getBooleanQuery(clauses, true);
}
} else {
return getPrefixQuerySingle(field, termStr);
}
}
private Query getPrefixQuerySingle(String field, String termStr) throws ParseException {
currentMapper = null;
Analyzer oldAnalyzer = analyzer;
try {
@ -261,6 +478,11 @@ public class MapperQueryParser extends QueryParser {
}
}
return getPossiblyAnalyzedPrefixQuery(field, termStr);
} catch (RuntimeException e) {
if (settings.lenient()) {
return null;
}
throw e;
} finally {
analyzer = oldAnalyzer;
}
@ -321,6 +543,45 @@ public class MapperQueryParser extends QueryParser {
if (AllFieldMapper.NAME.equals(field) && termStr.equals("*")) {
return newMatchAllDocsQuery();
}
Collection<String> fields = extractMultiFields(field);
if (fields != null) {
if (fields.size() == 1) {
return getWildcardQuerySingle(fields.iterator().next(), termStr);
}
if (settings.useDisMax()) {
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker());
boolean added = false;
for (String mField : fields) {
Query q = getWildcardQuerySingle(mField, termStr);
if (q != null) {
added = true;
applyBoost(mField, q);
disMaxQuery.add(q);
}
}
if (!added) {
return null;
}
return disMaxQuery;
} else {
List<BooleanClause> clauses = new ArrayList<BooleanClause>();
for (String mField : fields) {
Query q = getWildcardQuerySingle(mField, termStr);
if (q != null) {
applyBoost(mField, q);
clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD));
}
}
if (clauses.size() == 0) // happens for stopwords
return null;
return getBooleanQuery(clauses, true);
}
} else {
return getWildcardQuerySingle(field, termStr);
}
}
private Query getWildcardQuerySingle(String field, String termStr) throws ParseException {
String indexedNameField = field;
currentMapper = null;
Analyzer oldAnalyzer = analyzer;
@ -337,6 +598,11 @@ public class MapperQueryParser extends QueryParser {
return wrapSmartNameQuery(getPossiblyAnalyzedWildcardQuery(indexedNameField, termStr), fieldMappers, parseContext);
}
return getPossiblyAnalyzedWildcardQuery(indexedNameField, termStr);
} catch (RuntimeException e) {
if (settings.lenient()) {
return null;
}
throw e;
} finally {
analyzer = oldAnalyzer;
}
@ -414,4 +680,31 @@ public class MapperQueryParser extends QueryParser {
}
return optimizeQuery(fixNegativeQueryIfNeeded(q));
}
private void applyBoost(String field, Query q) {
if (settings.boosts() != null) {
float boost = settings.boosts().get(field);
q.setBoost(boost);
}
}
private void applySlop(Query q, int slop) {
if (q instanceof PhraseQuery) {
((PhraseQuery) q).setSlop(slop);
} else if (q instanceof MultiPhraseQuery) {
((MultiPhraseQuery) q).setSlop(slop);
}
}
private Collection<String> extractMultiFields(String field) {
Collection<String> fields = null;
if (field != null) {
if (Regex.isSimpleMatchPattern(field)) {
fields = parseContext.mapperService().simpleMatchToIndexNames(field);
}
} else {
fields = settings.fields();
}
return fields;
}
}

View File

@ -1,273 +0,0 @@
/*
* Licensed to ElasticSearch and Shay Banon under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. ElasticSearch 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.apache.lucene.queryParser;
import org.apache.lucene.search.*;
import org.elasticsearch.index.query.QueryParseContext;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
public class MultiFieldMapperQueryParser extends MapperQueryParser {
private MultiFieldQueryParserSettings settings;
public MultiFieldMapperQueryParser(QueryParseContext parseContext) {
super(parseContext);
}
public MultiFieldMapperQueryParser(MultiFieldQueryParserSettings settings, QueryParseContext parseContext) {
super(settings, parseContext);
this.settings = settings;
}
public void reset(MultiFieldQueryParserSettings settings) {
super.reset(settings);
this.settings = settings;
}
@Override
public Query getFieldQuery(String xField, String queryText, boolean quoted) throws ParseException {
if (xField != null) {
return super.getFieldQuery(xField, queryText, quoted);
}
if (settings.useDisMax()) {
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker());
boolean added = false;
for (String field : settings.fields()) {
Query q = super.getFieldQuery(field, queryText, quoted);
if (q != null) {
added = true;
applyBoost(field, q);
disMaxQuery.add(q);
}
}
if (!added) {
return null;
}
return disMaxQuery;
} else {
List<BooleanClause> clauses = new ArrayList<BooleanClause>();
for (String field : settings.fields()) {
Query q = super.getFieldQuery(field, queryText, true);
if (q != null) {
applyBoost(field, q);
clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD));
}
}
if (clauses.size() == 0) // happens for stopwords
return null;
return getBooleanQuery(clauses, true);
}
}
@Override
public Query getFieldQuery(String xField, String queryText, int slop) throws ParseException {
if (xField != null) {
Query q = super.getFieldQuery(xField, queryText, true);
applySlop(q, slop);
return q;
}
if (settings.useDisMax()) {
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker());
boolean added = false;
for (String field : settings.fields()) {
Query q = super.getFieldQuery(field, queryText, true);
if (q != null) {
added = true;
applyBoost(field, q);
applySlop(q, slop);
disMaxQuery.add(q);
}
}
if (!added) {
return null;
}
return disMaxQuery;
} else {
List<BooleanClause> clauses = new ArrayList<BooleanClause>();
for (String field : settings.fields()) {
Query q = super.getFieldQuery(field, queryText, true);
if (q != null) {
applyBoost(field, q);
applySlop(q, slop);
clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD));
}
}
if (clauses.size() == 0) // happens for stopwords
return null;
return getBooleanQuery(clauses, true);
}
}
@Override
protected Query getRangeQuery(String xField, String part1, String part2, boolean inclusive) throws ParseException {
if (xField != null) {
return super.getRangeQuery(xField, part1, part2, inclusive);
}
if (settings.useDisMax()) {
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker());
boolean added = false;
for (String field : settings.fields()) {
Query q = super.getRangeQuery(field, part1, part2, inclusive);
if (q != null) {
added = true;
applyBoost(field, q);
disMaxQuery.add(q);
}
}
if (!added) {
return null;
}
return disMaxQuery;
} else {
List<BooleanClause> clauses = new ArrayList<BooleanClause>();
for (String field : settings.fields()) {
Query q = super.getRangeQuery(field, part1, part2, inclusive);
if (q != null) {
applyBoost(field, q);
clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD));
}
}
if (clauses.size() == 0) // happens for stopwords
return null;
return getBooleanQuery(clauses, true);
}
}
@Override
protected Query getPrefixQuery(String xField, String termStr) throws ParseException {
if (xField != null) {
return super.getPrefixQuery(xField, termStr);
}
if (settings.useDisMax()) {
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker());
boolean added = false;
for (String field : settings.fields()) {
Query q = super.getPrefixQuery(field, termStr);
if (q != null) {
added = true;
applyBoost(field, q);
disMaxQuery.add(q);
}
}
if (!added) {
return null;
}
return disMaxQuery;
} else {
List<BooleanClause> clauses = new ArrayList<BooleanClause>();
for (String field : settings.fields()) {
Query q = super.getPrefixQuery(field, termStr);
if (q != null) {
applyBoost(field, q);
clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD));
}
}
if (clauses.size() == 0) // happens for stopwords
return null;
return getBooleanQuery(clauses, true);
}
}
@Override
protected Query getWildcardQuery(String xField, String termStr) throws ParseException {
if (xField != null) {
return super.getWildcardQuery(xField, termStr);
}
if (settings.useDisMax()) {
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker());
boolean added = false;
for (String field : settings.fields()) {
Query q = super.getWildcardQuery(field, termStr);
if (q != null) {
added = true;
applyBoost(field, q);
disMaxQuery.add(q);
}
}
if (!added) {
return null;
}
return disMaxQuery;
} else {
List<BooleanClause> clauses = new ArrayList<BooleanClause>();
for (String field : settings.fields()) {
Query q = super.getWildcardQuery(field, termStr);
if (q != null) {
applyBoost(field, q);
clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD));
}
}
if (clauses.size() == 0) // happens for stopwords
return null;
return getBooleanQuery(clauses, true);
}
}
@Override
protected Query getFuzzyQuery(String xField, String termStr, float minSimilarity) throws ParseException {
if (xField != null) {
return super.getFuzzyQuery(xField, termStr, minSimilarity);
}
if (settings.useDisMax()) {
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(settings.tieBreaker());
boolean added = false;
for (String field : settings.fields()) {
Query q = super.getFuzzyQuery(field, termStr, minSimilarity);
if (q != null) {
added = true;
applyBoost(field, q);
disMaxQuery.add(q);
}
}
if (!added) {
return null;
}
return disMaxQuery;
} else {
List<BooleanClause> clauses = new ArrayList<BooleanClause>();
for (String field : settings.fields()) {
Query q = super.getFuzzyQuery(field, termStr, minSimilarity);
applyBoost(field, q);
clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD));
}
return getBooleanQuery(clauses, true);
}
}
private void applyBoost(String field, Query q) {
if (settings.boosts() != null) {
float boost = settings.boosts().get(field);
q.setBoost(boost);
}
}
private void applySlop(Query q, int slop) {
if (q instanceof PhraseQuery) {
((PhraseQuery) q).setSlop(slop);
} else if (q instanceof MultiPhraseQuery) {
((MultiPhraseQuery) q).setSlop(slop);
}
}
}

View File

@ -1,98 +0,0 @@
/*
* Licensed to ElasticSearch and Shay Banon under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. ElasticSearch 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.apache.lucene.queryParser;
import gnu.trove.map.hash.TObjectFloatHashMap;
import java.util.List;
/**
*
*/
public class MultiFieldQueryParserSettings extends QueryParserSettings {
List<String> fields = null;
TObjectFloatHashMap<String> boosts = null;
float tieBreaker = 0.0f;
boolean useDisMax = true;
public List<String> fields() {
return fields;
}
public void fields(List<String> fields) {
this.fields = fields;
}
public TObjectFloatHashMap<String> boosts() {
return boosts;
}
public void boosts(TObjectFloatHashMap<String> boosts) {
this.boosts = boosts;
}
public float tieBreaker() {
return tieBreaker;
}
public void tieBreaker(float tieBreaker) {
this.tieBreaker = tieBreaker;
}
public boolean useDisMax() {
return useDisMax;
}
public void useDisMax(boolean useDisMax) {
this.useDisMax = useDisMax;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
// if there is a single field, its the same as single mapper parser / settings
// we take for that also in the code
if (fields == null || fields.size() == 1) return super.equals(o);
if (!super.equals(o)) return false;
MultiFieldQueryParserSettings that = (MultiFieldQueryParserSettings) o;
if (Float.compare(that.tieBreaker, tieBreaker) != 0) return false;
if (useDisMax != that.useDisMax) return false;
if (boosts != null ? !boosts.equals(that.boosts) : that.boosts != null) return false;
if (fields != null ? !fields.equals(that.fields) : that.fields != null) return false;
return true;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (fields != null ? fields.hashCode() : 0);
result = 31 * result + (boosts != null ? boosts.hashCode() : 0);
result = 31 * result + (tieBreaker != +0.0f ? Float.floatToIntBits(tieBreaker) : 0);
result = 31 * result + (useDisMax ? 1 : 0);
return result;
}
}

View File

@ -19,10 +19,13 @@
package org.apache.lucene.queryParser;
import gnu.trove.map.hash.TObjectFloatHashMap;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.MultiTermQuery;
import java.util.List;
/**
*
*/
@ -53,6 +56,12 @@ public class QueryParserSettings {
private String minimumShouldMatch;
private boolean lenient;
List<String> fields = null;
TObjectFloatHashMap<String> boosts = null;
float tieBreaker = 0.0f;
boolean useDisMax = true;
public String queryString() {
return queryString;
}
@ -221,6 +230,38 @@ public class QueryParserSettings {
return this.lenient;
}
public List<String> fields() {
return fields;
}
public void fields(List<String> fields) {
this.fields = fields;
}
public TObjectFloatHashMap<String> boosts() {
return boosts;
}
public void boosts(TObjectFloatHashMap<String> boosts) {
this.boosts = boosts;
}
public float tieBreaker() {
return tieBreaker;
}
public void tieBreaker(float tieBreaker) {
this.tieBreaker = tieBreaker;
}
public boolean useDisMax() {
return useDisMax;
}
public void useDisMax(boolean useDisMax) {
this.useDisMax = useDisMax;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@ -259,6 +300,11 @@ public class QueryParserSettings {
return false;
}
if (Float.compare(that.tieBreaker, tieBreaker) != 0) return false;
if (useDisMax != that.useDisMax) return false;
if (boosts != null ? !boosts.equals(that.boosts) : that.boosts != null) return false;
if (fields != null ? !fields.equals(that.fields) : that.fields != null) return false;
return true;
}
@ -281,6 +327,11 @@ public class QueryParserSettings {
result = 31 * result + (forcedAnalyzer != null ? forcedAnalyzer.hashCode() : 0);
result = 31 * result + (forcedQuoteAnalyzer != null ? forcedQuoteAnalyzer.hashCode() : 0);
result = 31 * result + (analyzeWildcard ? 1 : 0);
result = 31 * result + (fields != null ? fields.hashCode() : 0);
result = 31 * result + (boosts != null ? boosts.hashCode() : 0);
result = 31 * result + (tieBreaker != +0.0f ? Float.floatToIntBits(tieBreaker) : 0);
result = 31 * result + (useDisMax ? 1 : 0);
return result;
}
}

View File

@ -156,7 +156,7 @@ public class FieldQueryParser implements QueryParser {
return query;
}
MapperQueryParser queryParser = parseContext.singleQueryParser(qpSettings);
MapperQueryParser queryParser = parseContext.queryParser(qpSettings);
try {
query = queryParser.parse(qpSettings.queryString());

View File

@ -22,8 +22,6 @@ package org.elasticsearch.index.query;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import org.apache.lucene.queryParser.MapperQueryParser;
import org.apache.lucene.queryParser.MultiFieldMapperQueryParser;
import org.apache.lucene.queryParser.MultiFieldQueryParserSettings;
import org.apache.lucene.queryParser.QueryParserSettings;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.Query;
@ -81,8 +79,6 @@ public class QueryParseContext {
private final MapperQueryParser queryParser = new MapperQueryParser(this);
private final MultiFieldMapperQueryParser multiFieldQueryParser = new MultiFieldMapperQueryParser(this);
private XContentParser parser;
public QueryParseContext(Index index, IndexQueryParserService indexQueryParser) {
@ -141,16 +137,11 @@ public class QueryParseContext {
return indexQueryParser.queryStringLenient();
}
public MapperQueryParser singleQueryParser(QueryParserSettings settings) {
public MapperQueryParser queryParser(QueryParserSettings settings) {
queryParser.reset(settings);
return queryParser;
}
public MultiFieldMapperQueryParser multiQueryParser(MultiFieldQueryParserSettings settings) {
multiFieldQueryParser.reset(settings);
return multiFieldQueryParser;
}
public Filter cacheFilter(Filter filter, @Nullable CacheKeyFilter.Key cacheKey) {
if (cacheKey != null) {
filter = new CacheKeyFilter.Wrapper(filter, cacheKey);

View File

@ -23,7 +23,6 @@ import com.google.common.collect.Lists;
import gnu.trove.impl.Constants;
import gnu.trove.map.hash.TObjectFloatHashMap;
import org.apache.lucene.queryParser.MapperQueryParser;
import org.apache.lucene.queryParser.MultiFieldQueryParserSettings;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParserSettings;
import org.apache.lucene.search.BooleanQuery;
@ -67,7 +66,7 @@ public class QueryStringQueryParser implements QueryParser {
public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
XContentParser parser = parseContext.parser();
MultiFieldQueryParserSettings qpSettings = new MultiFieldQueryParserSettings();
QueryParserSettings qpSettings = new QueryParserSettings();
qpSettings.defaultField(parseContext.defaultField());
qpSettings.lenient(parseContext.queryStringLenient());
qpSettings.analyzeWildcard(defaultAnalyzeWildcard);
@ -201,19 +200,7 @@ public class QueryStringQueryParser implements QueryParser {
return query;
}
MapperQueryParser queryParser;
if (qpSettings.fields() != null) {
if (qpSettings.fields().size() == 1) {
qpSettings.defaultField(qpSettings.fields().get(0));
queryParser = parseContext.singleQueryParser(qpSettings);
} else {
qpSettings.defaultField(null); // reset defaultField when using multi query parser
queryParser = parseContext.multiQueryParser(qpSettings);
}
} else {
queryParser = parseContext.singleQueryParser(qpSettings);
}
MapperQueryParser queryParser = parseContext.queryParser(qpSettings);
try {
query = queryParser.parse(qpSettings.queryString());