Query DSL: queryString - allow to run against multiple fields, closes #48.
This commit is contained in:
parent
fbf9197b85
commit
fdd221e8ea
|
@ -35,7 +35,7 @@ import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.google.common.collect.Lists.*;
|
import static com.google.common.collect.Lists.*;
|
||||||
import static org.elasticsearch.index.query.support.QueryParsers.*;
|
import static org.elasticsearch.util.lucene.search.Queries.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author kimchy (Shay Banon)
|
* @author kimchy (Shay Banon)
|
||||||
|
|
|
@ -77,6 +77,8 @@ public class DisMaxJsonQueryParser extends AbstractIndexComponent implements Jso
|
||||||
boost = jp.getFloatValue();
|
boost = jp.getFloatValue();
|
||||||
} else if ("tieBreakerMultiplier".equals(currentFieldName)) {
|
} else if ("tieBreakerMultiplier".equals(currentFieldName)) {
|
||||||
tieBreakerMultiplier = jp.getFloatValue();
|
tieBreakerMultiplier = jp.getFloatValue();
|
||||||
|
} else if ("tieBreaker".equals(currentFieldName)) {
|
||||||
|
tieBreakerMultiplier = jp.getFloatValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ import org.elasticsearch.util.settings.Settings;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import static org.elasticsearch.index.query.support.QueryParsers.*;
|
import static org.elasticsearch.util.lucene.search.Queries.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author kimchy (shay.banon)
|
* @author kimchy (shay.banon)
|
||||||
|
|
|
@ -20,8 +20,12 @@
|
||||||
package org.elasticsearch.index.query.json;
|
package org.elasticsearch.index.query.json;
|
||||||
|
|
||||||
import org.elasticsearch.util.json.JsonBuilder;
|
import org.elasticsearch.util.json.JsonBuilder;
|
||||||
|
import org.elasticsearch.util.trove.ExtTObjectFloatHashMap;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.google.common.collect.Lists.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author kimchy (Shay Banon)
|
* @author kimchy (Shay Banon)
|
||||||
|
@ -55,6 +59,14 @@ public class QueryStringJsonQueryBuilder extends BaseJsonQueryBuilder {
|
||||||
|
|
||||||
private int phraseSlop = -1;
|
private int phraseSlop = -1;
|
||||||
|
|
||||||
|
private List<String> fields;
|
||||||
|
|
||||||
|
private ExtTObjectFloatHashMap<String> fieldsBoosts;
|
||||||
|
|
||||||
|
private Boolean useDisMax;
|
||||||
|
|
||||||
|
private float tieBreaker = -1;
|
||||||
|
|
||||||
public QueryStringJsonQueryBuilder(String queryString) {
|
public QueryStringJsonQueryBuilder(String queryString) {
|
||||||
this.queryString = queryString;
|
this.queryString = queryString;
|
||||||
}
|
}
|
||||||
|
@ -64,6 +76,50 @@ public class QueryStringJsonQueryBuilder extends BaseJsonQueryBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a field to run the query string against.
|
||||||
|
*/
|
||||||
|
public QueryStringJsonQueryBuilder field(String field) {
|
||||||
|
if (fields == null) {
|
||||||
|
fields = newArrayList();
|
||||||
|
}
|
||||||
|
fields.add(field);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a field to run the query string against with a specific boost.
|
||||||
|
*/
|
||||||
|
public QueryStringJsonQueryBuilder field(String field, float boost) {
|
||||||
|
if (fields == null) {
|
||||||
|
fields = newArrayList();
|
||||||
|
}
|
||||||
|
fields.add(field);
|
||||||
|
if (fieldsBoosts == null) {
|
||||||
|
fieldsBoosts = new ExtTObjectFloatHashMap<String>().defaultReturnValue(-1);
|
||||||
|
}
|
||||||
|
fieldsBoosts.put(field, boost);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When more than one field is used with the query string, should queries be combined using
|
||||||
|
* dis max, or boolean query. Defaults to dis max (<tt>true</tt>).
|
||||||
|
*/
|
||||||
|
public QueryStringJsonQueryBuilder useDisMax(boolean useDisMax) {
|
||||||
|
this.useDisMax = useDisMax;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When more than one field is used with the query string, and combined queries are using
|
||||||
|
* dis max, control the tie breaker for it.
|
||||||
|
*/
|
||||||
|
public QueryStringJsonQueryBuilder tieBreaker(float tieBreaker) {
|
||||||
|
this.tieBreaker = tieBreaker;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public QueryStringJsonQueryBuilder defaultOperator(Operator defaultOperator) {
|
public QueryStringJsonQueryBuilder defaultOperator(Operator defaultOperator) {
|
||||||
this.defaultOperator = defaultOperator;
|
this.defaultOperator = defaultOperator;
|
||||||
return this;
|
return this;
|
||||||
|
@ -115,6 +171,26 @@ public class QueryStringJsonQueryBuilder extends BaseJsonQueryBuilder {
|
||||||
if (defaultField != null) {
|
if (defaultField != null) {
|
||||||
builder.field("defaultField", defaultField);
|
builder.field("defaultField", defaultField);
|
||||||
}
|
}
|
||||||
|
if (fields != null) {
|
||||||
|
builder.startArray("fields");
|
||||||
|
for (String field : fields) {
|
||||||
|
float boost = -1;
|
||||||
|
if (fieldsBoosts != null) {
|
||||||
|
boost = fieldsBoosts.get(field);
|
||||||
|
}
|
||||||
|
if (boost != -1) {
|
||||||
|
field += "^" + boost;
|
||||||
|
}
|
||||||
|
builder.string(field);
|
||||||
|
}
|
||||||
|
builder.endArray();
|
||||||
|
}
|
||||||
|
if (useDisMax != null) {
|
||||||
|
builder.field("useDisMax", useDisMax);
|
||||||
|
}
|
||||||
|
if (tieBreaker != -1) {
|
||||||
|
builder.field("tieBreaker", tieBreaker);
|
||||||
|
}
|
||||||
if (defaultOperator != null) {
|
if (defaultOperator != null) {
|
||||||
builder.field("defaultOperator", defaultOperator.name().toLowerCase());
|
builder.field("defaultOperator", defaultOperator.name().toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.query.json;
|
package org.elasticsearch.index.query.json;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.queryParser.ParseException;
|
import org.apache.lucene.queryParser.ParseException;
|
||||||
|
@ -32,12 +33,15 @@ import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.analysis.AnalysisService;
|
import org.elasticsearch.index.analysis.AnalysisService;
|
||||||
import org.elasticsearch.index.query.QueryParsingException;
|
import org.elasticsearch.index.query.QueryParsingException;
|
||||||
import org.elasticsearch.index.query.support.MapperQueryParser;
|
import org.elasticsearch.index.query.support.MapperQueryParser;
|
||||||
|
import org.elasticsearch.index.query.support.MultiFieldMapperQueryParser;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import org.elasticsearch.util.settings.Settings;
|
import org.elasticsearch.util.settings.Settings;
|
||||||
|
import org.elasticsearch.util.trove.ExtTObjectFloatHashMap;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.elasticsearch.index.query.support.QueryParsers.*;
|
import static org.elasticsearch.util.lucene.search.Queries.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author kimchy (Shay Banon)
|
* @author kimchy (Shay Banon)
|
||||||
|
@ -74,12 +78,46 @@ public class QueryStringJsonQueryParser extends AbstractIndexComponent implement
|
||||||
float boost = 1.0f;
|
float boost = 1.0f;
|
||||||
boolean escape = false;
|
boolean escape = false;
|
||||||
Analyzer analyzer = null;
|
Analyzer analyzer = null;
|
||||||
|
List<String> fields = null;
|
||||||
|
ExtTObjectFloatHashMap<String> boosts = null;
|
||||||
|
float tieBreaker = 0.0f;
|
||||||
|
boolean useDisMax = true;
|
||||||
|
|
||||||
String currentFieldName = null;
|
String currentFieldName = null;
|
||||||
JsonToken token;
|
JsonToken token;
|
||||||
while ((token = jp.nextToken()) != JsonToken.END_OBJECT) {
|
while ((token = jp.nextToken()) != JsonToken.END_OBJECT) {
|
||||||
if (token == JsonToken.FIELD_NAME) {
|
if (token == JsonToken.FIELD_NAME) {
|
||||||
currentFieldName = jp.getCurrentName();
|
currentFieldName = jp.getCurrentName();
|
||||||
|
} else if (token == JsonToken.START_ARRAY) {
|
||||||
|
if ("fields".equals(currentFieldName)) {
|
||||||
|
while ((token = jp.nextToken()) != JsonToken.END_ARRAY) {
|
||||||
|
String fField = null;
|
||||||
|
float fBoost = -1;
|
||||||
|
char[] text = jp.getTextCharacters();
|
||||||
|
int end = jp.getTextOffset() + jp.getTextLength();
|
||||||
|
for (int i = jp.getTextOffset(); i < end; i++) {
|
||||||
|
if (text[i] == '^') {
|
||||||
|
int relativeLocation = i - jp.getTextOffset();
|
||||||
|
fField = new String(text, jp.getTextOffset(), relativeLocation);
|
||||||
|
fBoost = Float.parseFloat(new String(text, i + 1, jp.getTextLength() - relativeLocation - 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fField == null) {
|
||||||
|
fField = jp.getText();
|
||||||
|
}
|
||||||
|
if (fields == null) {
|
||||||
|
fields = Lists.newArrayList();
|
||||||
|
}
|
||||||
|
fields.add(fField);
|
||||||
|
if (fBoost != -1) {
|
||||||
|
if (boosts == null) {
|
||||||
|
boosts = new ExtTObjectFloatHashMap<String>();
|
||||||
|
}
|
||||||
|
boosts.put(fField, fBoost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (token == JsonToken.VALUE_STRING) {
|
} else if (token == JsonToken.VALUE_STRING) {
|
||||||
if ("query".equals(currentFieldName)) {
|
if ("query".equals(currentFieldName)) {
|
||||||
queryString = jp.getText();
|
queryString = jp.getText();
|
||||||
|
@ -106,12 +144,16 @@ public class QueryStringJsonQueryParser extends AbstractIndexComponent implement
|
||||||
enablePositionIncrements = token == JsonToken.VALUE_TRUE;
|
enablePositionIncrements = token == JsonToken.VALUE_TRUE;
|
||||||
} else if ("escape".equals(currentFieldName)) {
|
} else if ("escape".equals(currentFieldName)) {
|
||||||
escape = token == JsonToken.VALUE_TRUE;
|
escape = token == JsonToken.VALUE_TRUE;
|
||||||
|
} else if ("useDisMax".equals(currentFieldName)) {
|
||||||
|
useDisMax = token == JsonToken.VALUE_TRUE;
|
||||||
}
|
}
|
||||||
} else if (token == JsonToken.VALUE_NUMBER_FLOAT) {
|
} else if (token == JsonToken.VALUE_NUMBER_FLOAT) {
|
||||||
if ("fuzzyMinSim".equals(currentFieldName)) {
|
if ("fuzzyMinSim".equals(currentFieldName)) {
|
||||||
fuzzyMinSim = jp.getFloatValue();
|
fuzzyMinSim = jp.getFloatValue();
|
||||||
} else if ("boost".equals(currentFieldName)) {
|
} else if ("boost".equals(currentFieldName)) {
|
||||||
boost = jp.getFloatValue();
|
boost = jp.getFloatValue();
|
||||||
|
} else if ("tieBreaker".equals(currentFieldName)) {
|
||||||
|
tieBreaker = jp.getFloatValue();
|
||||||
}
|
}
|
||||||
} else if (token == JsonToken.VALUE_NUMBER_INT) {
|
} else if (token == JsonToken.VALUE_NUMBER_INT) {
|
||||||
if ("fuzzyPrefixLength".equals(currentFieldName)) {
|
if ("fuzzyPrefixLength".equals(currentFieldName)) {
|
||||||
|
@ -130,6 +172,10 @@ public class QueryStringJsonQueryParser extends AbstractIndexComponent implement
|
||||||
enablePositionIncrements = jp.getIntValue() != 0;
|
enablePositionIncrements = jp.getIntValue() != 0;
|
||||||
} else if ("escape".equals(currentFieldName)) {
|
} else if ("escape".equals(currentFieldName)) {
|
||||||
escape = jp.getIntValue() != 0;
|
escape = jp.getIntValue() != 0;
|
||||||
|
} else if ("useDisMax".equals(currentFieldName)) {
|
||||||
|
escape = jp.getIntValue() != 0;
|
||||||
|
} else if ("tieBreaker".equals(currentFieldName)) {
|
||||||
|
tieBreaker = jp.getFloatValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,7 +186,19 @@ public class QueryStringJsonQueryParser extends AbstractIndexComponent implement
|
||||||
analyzer = parseContext.mapperService().searchAnalyzer();
|
analyzer = parseContext.mapperService().searchAnalyzer();
|
||||||
}
|
}
|
||||||
|
|
||||||
MapperQueryParser queryParser = new MapperQueryParser(defaultField, analyzer, parseContext.mapperService(), parseContext.filterCache());
|
MapperQueryParser queryParser;
|
||||||
|
if (fields != null) {
|
||||||
|
if (fields.size() == 1) {
|
||||||
|
queryParser = new MapperQueryParser(fields.get(0), analyzer, parseContext.mapperService(), parseContext.filterCache());
|
||||||
|
} else {
|
||||||
|
MultiFieldMapperQueryParser mQueryParser = new MultiFieldMapperQueryParser(fields, boosts, analyzer, parseContext.mapperService(), parseContext.filterCache());
|
||||||
|
mQueryParser.setTieBreaker(tieBreaker);
|
||||||
|
mQueryParser.setUseDisMax(useDisMax);
|
||||||
|
queryParser = mQueryParser;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
queryParser = new MapperQueryParser(defaultField, analyzer, parseContext.mapperService(), parseContext.filterCache());
|
||||||
|
}
|
||||||
queryParser.setEnablePositionIncrements(enablePositionIncrements);
|
queryParser.setEnablePositionIncrements(enablePositionIncrements);
|
||||||
queryParser.setLowercaseExpandedTerms(lowercaseExpandedTerms);
|
queryParser.setLowercaseExpandedTerms(lowercaseExpandedTerms);
|
||||||
queryParser.setAllowLeadingWildcard(allowLeadingWildcard);
|
queryParser.setAllowLeadingWildcard(allowLeadingWildcard);
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.elasticsearch.util.Nullable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.elasticsearch.index.query.support.QueryParsers.*;
|
import static org.elasticsearch.index.query.support.QueryParsers.*;
|
||||||
|
import static org.elasticsearch.util.lucene.search.Queries.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A query parser that uses the {@link MapperService} in order to build smarter
|
* A query parser that uses the {@link MapperService} in order to build smarter
|
||||||
|
@ -145,7 +146,7 @@ public class MapperQueryParser extends QueryParser {
|
||||||
if (q == null) {
|
if (q == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return fixNegativeQueryIfNeeded(q);
|
return optimizeQuery(fixNegativeQueryIfNeeded(q));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected FieldMapper fieldMapper(String smartName) {
|
protected FieldMapper fieldMapper(String smartName) {
|
||||||
|
|
|
@ -0,0 +1,251 @@
|
||||||
|
/*
|
||||||
|
* 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.support;
|
||||||
|
|
||||||
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
|
import org.apache.lucene.queryParser.ParseException;
|
||||||
|
import org.apache.lucene.search.*;
|
||||||
|
import org.elasticsearch.index.cache.filter.FilterCache;
|
||||||
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
|
import org.elasticsearch.util.Nullable;
|
||||||
|
import org.elasticsearch.util.trove.ExtTObjectFloatHashMap;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author kimchy (shay.banon)
|
||||||
|
*/
|
||||||
|
public class MultiFieldMapperQueryParser extends MapperQueryParser {
|
||||||
|
|
||||||
|
private List<String> fields;
|
||||||
|
|
||||||
|
private ExtTObjectFloatHashMap<String> boosts;
|
||||||
|
|
||||||
|
private float tieBreaker = 0.0f;
|
||||||
|
|
||||||
|
private boolean useDisMax = true;
|
||||||
|
|
||||||
|
public MultiFieldMapperQueryParser(List<String> fields, @Nullable ExtTObjectFloatHashMap<String> boosts, Analyzer analyzer, @Nullable MapperService mapperService, @Nullable FilterCache filterCache) {
|
||||||
|
super(null, analyzer, mapperService, filterCache);
|
||||||
|
this.fields = fields;
|
||||||
|
this.boosts = boosts;
|
||||||
|
if (this.boosts != null) {
|
||||||
|
boosts.defaultReturnValue(1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTieBreaker(float tieBreaker) {
|
||||||
|
this.tieBreaker = tieBreaker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUseDisMax(boolean useDisMax) {
|
||||||
|
this.useDisMax = useDisMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public Query getFieldQuery(String field, String queryText) throws ParseException {
|
||||||
|
return getFieldQuery(field, queryText, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public Query getFieldQuery(String xField, String queryText, int slop) throws ParseException {
|
||||||
|
if (xField != null) {
|
||||||
|
Query q = super.getFieldQuery(xField, queryText);
|
||||||
|
applySlop(q, slop);
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
if (useDisMax) {
|
||||||
|
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(tieBreaker);
|
||||||
|
boolean added = false;
|
||||||
|
for (String field : fields) {
|
||||||
|
Query q = super.getFieldQuery(field, queryText);
|
||||||
|
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 : fields) {
|
||||||
|
Query q = super.getFieldQuery(field, queryText);
|
||||||
|
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 (useDisMax) {
|
||||||
|
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(tieBreaker);
|
||||||
|
boolean added = false;
|
||||||
|
for (String field : 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 : 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 (useDisMax) {
|
||||||
|
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(tieBreaker);
|
||||||
|
boolean added = false;
|
||||||
|
for (String field : 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 : 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 (useDisMax) {
|
||||||
|
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(tieBreaker);
|
||||||
|
boolean added = false;
|
||||||
|
for (String field : 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 : 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 (useDisMax) {
|
||||||
|
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(tieBreaker);
|
||||||
|
boolean added = false;
|
||||||
|
for (String field : 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 : 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 (boosts != null) {
|
||||||
|
float boost = 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,8 +26,6 @@ import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.util.Nullable;
|
import org.elasticsearch.util.Nullable;
|
||||||
import org.elasticsearch.util.lucene.search.TermFilter;
|
import org.elasticsearch.util.lucene.search.TermFilter;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author kimchy (shay.banon)
|
* @author kimchy (shay.banon)
|
||||||
*/
|
*/
|
||||||
|
@ -37,58 +35,6 @@ public final class QueryParsers {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Optimizes the given query and returns the optimized version of it.
|
|
||||||
*/
|
|
||||||
public static Query optimizeQuery(Query q) {
|
|
||||||
if (q instanceof BooleanQuery) {
|
|
||||||
return optimizeBooleanQuery((BooleanQuery) q);
|
|
||||||
}
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BooleanQuery optimizeBooleanQuery(BooleanQuery q) {
|
|
||||||
BooleanQuery optimized = new BooleanQuery(q.isCoordDisabled());
|
|
||||||
optimized.setMinimumNumberShouldMatch(q.getMinimumNumberShouldMatch());
|
|
||||||
optimizeBooleanQuery(optimized, q);
|
|
||||||
return optimized;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void optimizeBooleanQuery(BooleanQuery optimized, BooleanQuery q) {
|
|
||||||
for (BooleanClause clause : q.clauses()) {
|
|
||||||
Query cq = clause.getQuery();
|
|
||||||
cq.setBoost(cq.getBoost() * q.getBoost());
|
|
||||||
if (cq instanceof BooleanQuery && !clause.isRequired() && !clause.isProhibited()) {
|
|
||||||
optimizeBooleanQuery(optimized, (BooleanQuery) cq);
|
|
||||||
} else {
|
|
||||||
optimized.add(clause);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isNegativeQuery(Query q) {
|
|
||||||
if (!(q instanceof BooleanQuery)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
List<BooleanClause> clauses = ((BooleanQuery) q).clauses();
|
|
||||||
if (clauses.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (BooleanClause clause : clauses) {
|
|
||||||
if (!clause.isProhibited()) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Query fixNegativeQueryIfNeeded(Query q) {
|
|
||||||
if (isNegativeQuery(q)) {
|
|
||||||
BooleanQuery newBq = (BooleanQuery) q.clone();
|
|
||||||
newBq.add(new MatchAllDocsQuery(), BooleanClause.Occur.MUST);
|
|
||||||
return newBq;
|
|
||||||
}
|
|
||||||
return q;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Query wrapSmartNameQuery(Query query, @Nullable MapperService.SmartNameFieldMappers smartFieldMappers,
|
public static Query wrapSmartNameQuery(Query query, @Nullable MapperService.SmartNameFieldMappers smartFieldMappers,
|
||||||
@Nullable FilterCache filterCache) {
|
@Nullable FilterCache filterCache) {
|
||||||
if (smartFieldMappers == null) {
|
if (smartFieldMappers == null) {
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* 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.util.lucene.search;
|
||||||
|
|
||||||
|
import org.apache.lucene.search.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author kimchy (shay.banon)
|
||||||
|
*/
|
||||||
|
public class Queries {
|
||||||
|
|
||||||
|
private final static Field disjuncts;
|
||||||
|
|
||||||
|
static {
|
||||||
|
Field disjunctsX;
|
||||||
|
try {
|
||||||
|
disjunctsX = DisjunctionMaxQuery.class.getDeclaredField("disjuncts");
|
||||||
|
disjunctsX.setAccessible(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
disjunctsX = null;
|
||||||
|
}
|
||||||
|
disjuncts = disjunctsX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Query> disMaxClauses(DisjunctionMaxQuery query) {
|
||||||
|
try {
|
||||||
|
return (List<Query>) disjuncts.get(query);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optimizes the given query and returns the optimized version of it.
|
||||||
|
*/
|
||||||
|
public static Query optimizeQuery(Query q) {
|
||||||
|
if (q instanceof BooleanQuery) {
|
||||||
|
return optimizeBooleanQuery((BooleanQuery) q);
|
||||||
|
}
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BooleanQuery optimizeBooleanQuery(BooleanQuery q) {
|
||||||
|
BooleanQuery optimized = new BooleanQuery(q.isCoordDisabled());
|
||||||
|
optimized.setMinimumNumberShouldMatch(q.getMinimumNumberShouldMatch());
|
||||||
|
optimizeBooleanQuery(optimized, q);
|
||||||
|
return optimized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void optimizeBooleanQuery(BooleanQuery optimized, BooleanQuery q) {
|
||||||
|
for (BooleanClause clause : q.clauses()) {
|
||||||
|
Query cq = clause.getQuery();
|
||||||
|
cq.setBoost(cq.getBoost() * q.getBoost());
|
||||||
|
if (cq instanceof BooleanQuery && !clause.isRequired() && !clause.isProhibited()) {
|
||||||
|
optimizeBooleanQuery(optimized, (BooleanQuery) cq);
|
||||||
|
} else {
|
||||||
|
optimized.add(clause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isNegativeQuery(Query q) {
|
||||||
|
if (!(q instanceof BooleanQuery)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
List<BooleanClause> clauses = ((BooleanQuery) q).clauses();
|
||||||
|
if (clauses.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (BooleanClause clause : clauses) {
|
||||||
|
if (!clause.isProhibited()) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Query fixNegativeQueryIfNeeded(Query q) {
|
||||||
|
if (isNegativeQuery(q)) {
|
||||||
|
BooleanQuery newBq = (BooleanQuery) q.clone();
|
||||||
|
newBq.add(new MatchAllDocsQuery(), BooleanClause.Occur.MUST);
|
||||||
|
return newBq;
|
||||||
|
}
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* 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.util.trove;
|
||||||
|
|
||||||
|
import org.elasticsearch.util.gnu.trove.TObjectFloatHashMap;
|
||||||
|
import org.elasticsearch.util.gnu.trove.TObjectHashingStrategy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author kimchy (shay.banon)
|
||||||
|
*/
|
||||||
|
public class ExtTObjectFloatHashMap<T> extends TObjectFloatHashMap<T> {
|
||||||
|
|
||||||
|
private float defaultReturnValue = 0;
|
||||||
|
|
||||||
|
public ExtTObjectFloatHashMap() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtTObjectFloatHashMap(int initialCapacity) {
|
||||||
|
super(initialCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtTObjectFloatHashMap(int initialCapacity, float loadFactor) {
|
||||||
|
super(initialCapacity, loadFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtTObjectFloatHashMap(TObjectHashingStrategy<T> ttObjectHashingStrategy) {
|
||||||
|
super(ttObjectHashingStrategy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtTObjectFloatHashMap(int initialCapacity, TObjectHashingStrategy<T> ttObjectHashingStrategy) {
|
||||||
|
super(initialCapacity, ttObjectHashingStrategy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtTObjectFloatHashMap(int initialCapacity, float loadFactor, TObjectHashingStrategy<T> ttObjectHashingStrategy) {
|
||||||
|
super(initialCapacity, loadFactor, ttObjectHashingStrategy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtTObjectFloatHashMap<T> defaultReturnValue(float defaultReturnValue) {
|
||||||
|
this.defaultReturnValue = defaultReturnValue;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public float get(T key) {
|
||||||
|
int index = index(key);
|
||||||
|
return index < 0 ? defaultReturnValue : _values[index];
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ import org.elasticsearch.index.cache.filter.none.NoneFilterCache;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.query.IndexQueryParser;
|
import org.elasticsearch.index.query.IndexQueryParser;
|
||||||
import org.elasticsearch.util.lucene.search.MoreLikeThisQuery;
|
import org.elasticsearch.util.lucene.search.MoreLikeThisQuery;
|
||||||
|
import org.elasticsearch.util.lucene.search.Queries;
|
||||||
import org.elasticsearch.util.lucene.search.TermFilter;
|
import org.elasticsearch.util.lucene.search.TermFilter;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -71,6 +72,73 @@ public class SimpleJsonIndexQueryParserTests {
|
||||||
assertThat(termQuery.getTerm(), equalTo(new Term("content", "test")));
|
assertThat(termQuery.getTerm(), equalTo(new Term("content", "test")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test public void testQueryStringFields1Builder() throws Exception {
|
||||||
|
IndexQueryParser queryParser = newQueryParser();
|
||||||
|
Query parsedQuery = queryParser.parse(queryString("test").field("content").field("name").useDisMax(false));
|
||||||
|
assertThat(parsedQuery, instanceOf(BooleanQuery.class));
|
||||||
|
BooleanQuery bQuery = (BooleanQuery) parsedQuery;
|
||||||
|
assertThat(bQuery.clauses().size(), equalTo(2));
|
||||||
|
assertThat(((TermQuery) bQuery.clauses().get(0).getQuery()).getTerm(), equalTo(new Term("content", "test")));
|
||||||
|
assertThat(((TermQuery) bQuery.clauses().get(1).getQuery()).getTerm(), equalTo(new Term("name", "test")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void testQueryStringFields1() throws Exception {
|
||||||
|
IndexQueryParser queryParser = newQueryParser();
|
||||||
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/json/query-fields1.json");
|
||||||
|
Query parsedQuery = queryParser.parse(query);
|
||||||
|
assertThat(parsedQuery, instanceOf(BooleanQuery.class));
|
||||||
|
BooleanQuery bQuery = (BooleanQuery) parsedQuery;
|
||||||
|
assertThat(bQuery.clauses().size(), equalTo(2));
|
||||||
|
assertThat(((TermQuery) bQuery.clauses().get(0).getQuery()).getTerm(), equalTo(new Term("content", "test")));
|
||||||
|
assertThat(((TermQuery) bQuery.clauses().get(1).getQuery()).getTerm(), equalTo(new Term("name", "test")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void testQueryStringFields2Builder() throws Exception {
|
||||||
|
IndexQueryParser queryParser = newQueryParser();
|
||||||
|
Query parsedQuery = queryParser.parse(queryString("test").field("content").field("name").useDisMax(true));
|
||||||
|
assertThat(parsedQuery, instanceOf(DisjunctionMaxQuery.class));
|
||||||
|
DisjunctionMaxQuery disMaxQuery = (DisjunctionMaxQuery) parsedQuery;
|
||||||
|
List<Query> disjuncts = Queries.disMaxClauses(disMaxQuery);
|
||||||
|
assertThat(((TermQuery) disjuncts.get(0)).getTerm(), equalTo(new Term("content", "test")));
|
||||||
|
assertThat(((TermQuery) disjuncts.get(1)).getTerm(), equalTo(new Term("name", "test")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void testQueryStringFields2() throws Exception {
|
||||||
|
IndexQueryParser queryParser = newQueryParser();
|
||||||
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/json/query-fields2.json");
|
||||||
|
Query parsedQuery = queryParser.parse(query);
|
||||||
|
assertThat(parsedQuery, instanceOf(DisjunctionMaxQuery.class));
|
||||||
|
DisjunctionMaxQuery disMaxQuery = (DisjunctionMaxQuery) parsedQuery;
|
||||||
|
List<Query> disjuncts = Queries.disMaxClauses(disMaxQuery);
|
||||||
|
assertThat(((TermQuery) disjuncts.get(0)).getTerm(), equalTo(new Term("content", "test")));
|
||||||
|
assertThat(((TermQuery) disjuncts.get(1)).getTerm(), equalTo(new Term("name", "test")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void testQueryStringFields3Builder() throws Exception {
|
||||||
|
IndexQueryParser queryParser = newQueryParser();
|
||||||
|
Query parsedQuery = queryParser.parse(queryString("test").field("content", 2.2f).field("name").useDisMax(true));
|
||||||
|
assertThat(parsedQuery, instanceOf(DisjunctionMaxQuery.class));
|
||||||
|
DisjunctionMaxQuery disMaxQuery = (DisjunctionMaxQuery) parsedQuery;
|
||||||
|
List<Query> disjuncts = Queries.disMaxClauses(disMaxQuery);
|
||||||
|
assertThat(((TermQuery) disjuncts.get(0)).getTerm(), equalTo(new Term("content", "test")));
|
||||||
|
assertThat((double) disjuncts.get(0).getBoost(), closeTo(2.2, 0.01));
|
||||||
|
assertThat(((TermQuery) disjuncts.get(1)).getTerm(), equalTo(new Term("name", "test")));
|
||||||
|
assertThat((double) disjuncts.get(1).getBoost(), closeTo(1, 0.01));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void testQueryStringFields3() throws Exception {
|
||||||
|
IndexQueryParser queryParser = newQueryParser();
|
||||||
|
String query = copyToStringFromClasspath("/org/elasticsearch/index/query/json/query-fields3.json");
|
||||||
|
Query parsedQuery = queryParser.parse(query);
|
||||||
|
assertThat(parsedQuery, instanceOf(DisjunctionMaxQuery.class));
|
||||||
|
DisjunctionMaxQuery disMaxQuery = (DisjunctionMaxQuery) parsedQuery;
|
||||||
|
List<Query> disjuncts = Queries.disMaxClauses(disMaxQuery);
|
||||||
|
assertThat(((TermQuery) disjuncts.get(0)).getTerm(), equalTo(new Term("content", "test")));
|
||||||
|
assertThat((double) disjuncts.get(0).getBoost(), closeTo(2.2, 0.01));
|
||||||
|
assertThat(((TermQuery) disjuncts.get(1)).getTerm(), equalTo(new Term("name", "test")));
|
||||||
|
assertThat((double) disjuncts.get(1).getBoost(), closeTo(1, 0.01));
|
||||||
|
}
|
||||||
|
|
||||||
@Test public void testMatchAllBuilder() throws Exception {
|
@Test public void testMatchAllBuilder() throws Exception {
|
||||||
IndexQueryParser queryParser = newQueryParser();
|
IndexQueryParser queryParser = newQueryParser();
|
||||||
Query parsedQuery = queryParser.parse(matchAllQuery().boost(1.2f).buildAsString());
|
Query parsedQuery = queryParser.parse(matchAllQuery().boost(1.2f).buildAsString());
|
||||||
|
@ -95,9 +163,7 @@ public class SimpleJsonIndexQueryParserTests {
|
||||||
DisjunctionMaxQuery disjunctionMaxQuery = (DisjunctionMaxQuery) parsedQuery;
|
DisjunctionMaxQuery disjunctionMaxQuery = (DisjunctionMaxQuery) parsedQuery;
|
||||||
assertThat((double) disjunctionMaxQuery.getBoost(), closeTo(1.2, 0.01));
|
assertThat((double) disjunctionMaxQuery.getBoost(), closeTo(1.2, 0.01));
|
||||||
|
|
||||||
Field field = disjunctionMaxQuery.getClass().getDeclaredField("disjuncts");
|
List<Query> disjuncts = Queries.disMaxClauses(disjunctionMaxQuery);
|
||||||
field.setAccessible(true);
|
|
||||||
List<Query> disjuncts = (List<Query>) field.get(disjunctionMaxQuery);
|
|
||||||
assertThat(disjuncts.size(), equalTo(2));
|
assertThat(disjuncts.size(), equalTo(2));
|
||||||
|
|
||||||
Query firstQ = disjuncts.get(0);
|
Query firstQ = disjuncts.get(0);
|
||||||
|
@ -117,9 +183,7 @@ public class SimpleJsonIndexQueryParserTests {
|
||||||
DisjunctionMaxQuery disjunctionMaxQuery = (DisjunctionMaxQuery) parsedQuery;
|
DisjunctionMaxQuery disjunctionMaxQuery = (DisjunctionMaxQuery) parsedQuery;
|
||||||
assertThat((double) disjunctionMaxQuery.getBoost(), closeTo(1.2, 0.01));
|
assertThat((double) disjunctionMaxQuery.getBoost(), closeTo(1.2, 0.01));
|
||||||
|
|
||||||
Field field = disjunctionMaxQuery.getClass().getDeclaredField("disjuncts");
|
List<Query> disjuncts = Queries.disMaxClauses(disjunctionMaxQuery);
|
||||||
field.setAccessible(true);
|
|
||||||
List<Query> disjuncts = (List<Query>) field.get(disjunctionMaxQuery);
|
|
||||||
assertThat(disjuncts.size(), equalTo(2));
|
assertThat(disjuncts.size(), equalTo(2));
|
||||||
|
|
||||||
Query firstQ = disjuncts.get(0);
|
Query firstQ = disjuncts.get(0);
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
queryString : {
|
||||||
|
fields : ["content", "name"],
|
||||||
|
useDisMax : false,
|
||||||
|
query: "test"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
queryString : {
|
||||||
|
fields : ["content", "name"],
|
||||||
|
useDisMax : true,
|
||||||
|
query: "test"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
queryString : {
|
||||||
|
fields : ["content^2.2", "name"],
|
||||||
|
useDisMax : true,
|
||||||
|
query: "test"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue