Skip to content

Commit

Permalink
Query DSL: queryString - allow to run against multiple fields, closes #…
Browse files Browse the repository at this point in the history
  • Loading branch information
kimchy committed Mar 1, 2010
1 parent fbf9197 commit fdd221e
Show file tree
Hide file tree
Showing 14 changed files with 652 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
import java.util.List;

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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ public class DisMaxJsonQueryParser extends AbstractIndexComponent implements Jso
boost = jp.getFloatValue();
} else if ("tieBreakerMultiplier".equals(currentFieldName)) {
tieBreakerMultiplier = jp.getFloatValue();
} else if ("tieBreaker".equals(currentFieldName)) {
tieBreakerMultiplier = jp.getFloatValue();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

import java.io.IOException;

import static org.elasticsearch.index.query.support.QueryParsers.*;
import static org.elasticsearch.util.lucene.search.Queries.*;

/**
* @author kimchy (shay.banon)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@
package org.elasticsearch.index.query.json;

import org.elasticsearch.util.json.JsonBuilder;
import org.elasticsearch.util.trove.ExtTObjectFloatHashMap;

import java.io.IOException;
import java.util.List;

import static com.google.common.collect.Lists.*;

/**
* @author kimchy (Shay Banon)
Expand Down Expand Up @@ -55,6 +59,14 @@ public static enum Operator {

private int phraseSlop = -1;

private List<String> fields;

private ExtTObjectFloatHashMap<String> fieldsBoosts;

private Boolean useDisMax;

private float tieBreaker = -1;

public QueryStringJsonQueryBuilder(String queryString) {
this.queryString = queryString;
}
Expand All @@ -64,6 +76,50 @@ public QueryStringJsonQueryBuilder defaultField(String defaultField) {
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) {
this.defaultOperator = defaultOperator;
return this;
Expand Down Expand Up @@ -115,6 +171,26 @@ public QueryStringJsonQueryBuilder phraseSlop(int phraseSlop) {
if (defaultField != null) {
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) {
builder.field("defaultOperator", defaultOperator.name().toLowerCase());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package org.elasticsearch.index.query.json;

import com.google.common.collect.Lists;
import com.google.inject.Inject;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryParser.ParseException;
Expand All @@ -32,12 +33,15 @@
import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.query.QueryParsingException;
import org.elasticsearch.index.query.support.MapperQueryParser;
import org.elasticsearch.index.query.support.MultiFieldMapperQueryParser;
import org.elasticsearch.index.settings.IndexSettings;
import org.elasticsearch.util.settings.Settings;
import org.elasticsearch.util.trove.ExtTObjectFloatHashMap;

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)
Expand Down Expand Up @@ -74,12 +78,46 @@ public class QueryStringJsonQueryParser extends AbstractIndexComponent implement
float boost = 1.0f;
boolean escape = false;
Analyzer analyzer = null;
List<String> fields = null;
ExtTObjectFloatHashMap<String> boosts = null;
float tieBreaker = 0.0f;
boolean useDisMax = true;

String currentFieldName = null;
JsonToken token;
while ((token = jp.nextToken()) != JsonToken.END_OBJECT) {
if (token == JsonToken.FIELD_NAME) {
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) {
if ("query".equals(currentFieldName)) {
queryString = jp.getText();
Expand All @@ -106,12 +144,16 @@ public class QueryStringJsonQueryParser extends AbstractIndexComponent implement
enablePositionIncrements = token == JsonToken.VALUE_TRUE;
} else if ("escape".equals(currentFieldName)) {
escape = token == JsonToken.VALUE_TRUE;
} else if ("useDisMax".equals(currentFieldName)) {
useDisMax = token == JsonToken.VALUE_TRUE;
}
} else if (token == JsonToken.VALUE_NUMBER_FLOAT) {
if ("fuzzyMinSim".equals(currentFieldName)) {
fuzzyMinSim = jp.getFloatValue();
} else if ("boost".equals(currentFieldName)) {
boost = jp.getFloatValue();
} else if ("tieBreaker".equals(currentFieldName)) {
tieBreaker = jp.getFloatValue();
}
} else if (token == JsonToken.VALUE_NUMBER_INT) {
if ("fuzzyPrefixLength".equals(currentFieldName)) {
Expand All @@ -130,6 +172,10 @@ public class QueryStringJsonQueryParser extends AbstractIndexComponent implement
enablePositionIncrements = jp.getIntValue() != 0;
} else if ("escape".equals(currentFieldName)) {
escape = jp.getIntValue() != 0;
} else if ("useDisMax".equals(currentFieldName)) {
escape = jp.getIntValue() != 0;
} else if ("tieBreaker".equals(currentFieldName)) {
tieBreaker = jp.getFloatValue();
}
}
}
Expand All @@ -140,7 +186,19 @@ public class QueryStringJsonQueryParser extends AbstractIndexComponent implement
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.setLowercaseExpandedTerms(lowercaseExpandedTerms);
queryParser.setAllowLeadingWildcard(allowLeadingWildcard);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import java.util.List;

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
Expand Down Expand Up @@ -145,7 +146,7 @@ public MapperQueryParser(String defaultField, Analyzer analyzer,
if (q == null) {
return null;
}
return fixNegativeQueryIfNeeded(q);
return optimizeQuery(fixNegativeQueryIfNeeded(q));
}

protected FieldMapper fieldMapper(String smartName) {
Expand Down

0 comments on commit fdd221e

Please sign in to comment.