Skip to content

Commit

Permalink
Fix FuzzyQuery to properly handle Object, number, dates or String.
Browse files Browse the repository at this point in the history
This makes FuzzyQueryBuilder and Parser take an Object as a value using the
same logic as termQuery, so that numbers, dates or Strings would be properly
handled.

Relates #11865
Closes #12020
  • Loading branch information
alexksikes committed Jul 8, 2015
1 parent 786d034 commit a6c0007
Show file tree
Hide file tree
Showing 12 changed files with 92 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,7 @@
import org.apache.lucene.index.Term;
import org.apache.lucene.index.Terms;
import org.apache.lucene.queries.TermsQuery;
import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.RegexpQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.search.*;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.action.fieldstats.FieldStats;
import org.elasticsearch.common.Nullable;
Expand Down Expand Up @@ -463,8 +456,8 @@ public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower
includeLower, includeUpper);
}

public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
return new FuzzyQuery(createTerm(value), fuzziness.asDistance(value), prefixLength, maxExpansions, transpositions);
public Query fuzzyQuery(Object value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
return new FuzzyQuery(createTerm(value), fuzziness.asDistance(BytesRefs.toString(value)), prefixLength, maxExpansions, transpositions);
}

public Query prefixQuery(Object value, @Nullable MultiTermQuery.RewriteMethod method, @Nullable QueryParseContext context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower
}

@Override
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
byte iValue = Byte.parseByte(value);
public Query fuzzyQuery(Object value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
byte iValue = parseValue(value);
byte iSim = fuzziness.asByte();
return NumericRangeQuery.newIntRange(names().indexName(), numericPrecisionStep(),
iValue - iSim,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,8 @@ public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower
}

@Override
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
long iValue = dateMathParser().parse(value, now());
public Query fuzzyQuery(Object value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
long iValue = parseValue(value);
long iSim;
try {
iSim = fuzziness.asTimeValue().millis();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
package org.elasticsearch.index.mapper.core;

import com.carrotsearch.hppc.DoubleArrayList;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Field;
Expand Down Expand Up @@ -178,8 +177,8 @@ public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower
}

@Override
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
double iValue = Double.parseDouble(value);
public Query fuzzyQuery(Object value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
double iValue = parseDoubleValue(value);
double iSim = fuzziness.asDouble();
return NumericRangeQuery.newDoubleRange(names().indexName(), numericPrecisionStep(),
iValue - iSim,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
package org.elasticsearch.index.mapper.core;

import com.carrotsearch.hppc.FloatArrayList;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Field;
Expand Down Expand Up @@ -179,8 +178,8 @@ public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower
}

@Override
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
float iValue = Float.parseFloat(value);
public Query fuzzyQuery(Object value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
float iValue = parseValue(value);
final float iSim = fuzziness.asFloat();
return NumericRangeQuery.newFloatRange(names().indexName(), numericPrecisionStep(),
iValue - iSim,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower
}

@Override
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
int iValue = Integer.parseInt(value);
public Query fuzzyQuery(Object value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
int iValue = parseValue(value);
int iSim = fuzziness.asInt();
return NumericRangeQuery.newIntRange(names().indexName(), numericPrecisionStep(),
iValue - iSim,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower
}

@Override
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
long iValue = Long.parseLong(value);
public Query fuzzyQuery(Object value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
long iValue = parseLongValue(value);
final long iSim = fuzziness.asLong();
return NumericRangeQuery.newLongRange(names().indexName(), numericPrecisionStep(),
iValue - iSim,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
package org.elasticsearch.index.mapper.core;

import com.carrotsearch.hppc.LongArrayList;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.NumericTokenStream;
import org.apache.lucene.analysis.TokenStream;
Expand All @@ -42,13 +41,7 @@
import org.elasticsearch.common.util.CollectionUtils;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MergeMappingException;
import org.elasticsearch.index.mapper.MergeResult;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.*;
import org.elasticsearch.index.mapper.internal.AllFieldMapper;

import java.io.IOException;
Expand Down Expand Up @@ -158,7 +151,7 @@ public Object valueForSearch(Object value) {
}

@Override
public abstract Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions);
public abstract Query fuzzyQuery(Object value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions);

@Override
public boolean useTermQueryWithQueryString() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower
}

@Override
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
short iValue = Short.parseShort(value);
public Query fuzzyQuery(Object value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
short iValue = parseValue(value);
short iSim = fuzziness.asShort();
return NumericRangeQuery.newIntRange(names().indexName(), numericPrecisionStep(),
iValue - iSim,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
package org.elasticsearch.index.mapper.ip;

import com.google.common.net.InetAddresses;

import org.apache.lucene.analysis.NumericTokenStream;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexOptions;
Expand Down Expand Up @@ -218,8 +217,8 @@ public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower
}

@Override
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
long iValue = ipToLong(value);
public Query fuzzyQuery(Object value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
long iValue = parseValue(value);
long iSim;
try {
iSim = ipToLong(fuzziness.asString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,77 @@ public class FuzzyQueryBuilder extends MultiTermQueryBuilder implements Boostabl
private String queryName;

/**
* Constructs a new term query.
* Constructs a new fuzzy query.
*
* @param name The name of the field
* @param value The value of the term
* @param value The value of the text
*/
public FuzzyQueryBuilder(String name, Object value) {
this.name = name;
this.value = value;
}

/**
* Constructs a new fuzzy query.
*
* @param name The name of the field
* @param value The value of the text
*/
public FuzzyQueryBuilder(String name, String value) {
this(name, (Object) value);
}

/**
* Constructs a new fuzzy query.
*
* @param name The name of the field
* @param value The value of the text
*/
public FuzzyQueryBuilder(String name, int value) {
this(name, (Object) value);
}

/**
* Constructs a new fuzzy query.
*
* @param name The name of the field
* @param value The value of the text
*/
public FuzzyQueryBuilder(String name, long value) {
this(name, (Object) value);
}

/**
* Constructs a new fuzzy query.
*
* @param name The name of the field
* @param value The value of the text
*/
public FuzzyQueryBuilder(String name, float value) {
this(name, (Object) value);
}

/**
* Constructs a new fuzzy query.
*
* @param name The name of the field
* @param value The value of the text
*/
public FuzzyQueryBuilder(String name, double value) {
this(name, (Object) value);
}

// NO COMMIT: not sure we should also allow boolean?
/**
* Constructs a new fuzzy query.
*
* @param name The name of the field
* @param value The value of the text
*/
public FuzzyQueryBuilder(String name, boolean value) {
this(name, (Object) value);
}

/**
* Sets the boost for this query. Documents matching this query will (in addition to the normal
* weightings) have their score multiplied by the boost provided.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.apache.lucene.search.Query;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.mapper.MappedFieldType;
Expand Down Expand Up @@ -61,7 +62,7 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
}
String fieldName = parser.currentName();

String value = null;
Object value = null;
float boost = 1.0f;
Fuzziness fuzziness = DEFAULT_FUZZINESS;
int prefixLength = FuzzyQuery.defaultPrefixLength;
Expand All @@ -80,9 +81,9 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
currentFieldName = parser.currentName();
} else {
if ("term".equals(currentFieldName)) {
value = parser.text();
value = parser.objectBytes();
} else if ("value".equals(currentFieldName)) {
value = parser.text();
value = parser.objectBytes();
} else if ("boost".equals(currentFieldName)) {
boost = parser.floatValue();
} else if (parseContext.parseFieldMatcher().match(currentFieldName, FUZZINESS)) {
Expand All @@ -104,22 +105,23 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
}
parser.nextToken();
} else {
value = parser.text();
value = parser.objectBytes();
// move to the next token
parser.nextToken();
}

if (value == null) {
throw new QueryParsingException(parseContext, "No value specified for fuzzy query");
}

Query query = null;
MappedFieldType fieldType = parseContext.fieldMapper(fieldName);
if (fieldType != null) {
query = fieldType.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions);
}
if (query == null) {
query = new FuzzyQuery(new Term(fieldName, value), fuzziness.asDistance(value), prefixLength, maxExpansions, transpositions);
int maxEdits = fuzziness.asDistance(BytesRefs.toString(value));
query = new FuzzyQuery(new Term(fieldName, BytesRefs.toBytesRef(value)), maxEdits, prefixLength, maxExpansions, transpositions);
}
if (query instanceof MultiTermQuery) {
QueryParsers.setRewriteMethod((MultiTermQuery) query, rewriteMethod);
Expand Down

0 comments on commit a6c0007

Please sign in to comment.