diff --git a/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java index 6da0802225a..fea7690f9d5 100644 --- a/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java @@ -153,26 +153,23 @@ public interface FieldMapper { Object valueForSearch(Object value); /** - * Returns the indexed value. + * Returns the indexed value used to construct search "values". */ - BytesRef indexedValue(String value); + BytesRef indexedValueForSearch(Object value); /** - * Should the field query {@link #termQuery(String, org.elasticsearch.index.query.QueryParseContext)} be used when detecting this + * Should the field query {@link #termQuery(Object, org.elasticsearch.index.query.QueryParseContext)} be used when detecting this * field in query string. */ boolean useTermQueryWithQueryString(); - /** - * A field query for the specified value. - */ - Query termQuery(String value, @Nullable QueryParseContext context); + Query termQuery(Object value, @Nullable QueryParseContext context); - Filter termFilter(String value, @Nullable QueryParseContext context); + Filter termFilter(Object value, @Nullable QueryParseContext context); - Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context); + Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context); - Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context); + Filter rangeFilter(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context); Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions, boolean transpositions); diff --git a/src/main/java/org/elasticsearch/index/mapper/Uid.java b/src/main/java/org/elasticsearch/index/mapper/Uid.java index f8317aeadaa..1d080b8e693 100644 --- a/src/main/java/org/elasticsearch/index/mapper/Uid.java +++ b/src/main/java/org/elasticsearch/index/mapper/Uid.java @@ -77,6 +77,13 @@ public final class Uid { return type + DELIMITER; } + public static BytesRef typePrefixAsBytes(BytesRef type) { + BytesRef bytesRef = new BytesRef(type.length + 1); + bytesRef.append(type); + bytesRef.append(DELIMITER_BYTES); + return bytesRef; + } + public static String idFromUid(String uid) { int delimiterIndex = uid.indexOf(DELIMITER); // type is not allowed to have # in it..., ids can return uid.substring(delimiterIndex + 1); @@ -108,6 +115,22 @@ public final class Uid { return ref; } + public static BytesRef createUidAsBytes(String type, BytesRef id) { + BytesRef ref = new BytesRef(type.length() + 1 + id.length); + ref.copyChars(type); + ref.append(DELIMITER_BYTES); + ref.append(id); + return ref; + } + + public static BytesRef createUidAsBytes(BytesRef type, BytesRef id) { + BytesRef ref = new BytesRef(type.length + 1 + id.length); + ref.append(type); + ref.append(DELIMITER_BYTES); + ref.append(id); + return ref; + } + public static String createUid(String type, String id) { return createUid(new StringBuilder(), type, id); } @@ -116,6 +139,15 @@ public final class Uid { return sb.append(type).append(DELIMITER).append(id).toString(); } + public static boolean hasDelimiter(BytesRef uid) { + for (int i = uid.offset; i < uid.length; i++) { + if (uid.bytes[i] == DELIMITER_BYTE) { // 0x23 is equal to '#' + return true; + } + } + return false; + } + // LUCENE 4 UPGRADE: HashedBytesArray or BytesRef as return type? public static HashedBytesArray[] splitUidIntoTypeAndId(BytesRef uid) { int loc = -1; diff --git a/src/main/java/org/elasticsearch/index/mapper/core/AbstractFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/AbstractFieldMapper.java index ccd079b2d86..3dba37ed853 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/AbstractFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/AbstractFieldMapper.java @@ -383,8 +383,11 @@ public abstract class AbstractFieldMapper implements FieldMapper, Mapper { } @Override - public BytesRef indexedValue(String value) { - return new BytesRef(value); + public BytesRef indexedValueForSearch(Object value) { + if (value instanceof BytesRef) { + return (BytesRef) value; + } + return new BytesRef(value.toString()); } @Override @@ -398,30 +401,46 @@ public abstract class AbstractFieldMapper implements FieldMapper, Mapper { } @Override - public Query termQuery(String value, @Nullable QueryParseContext context) { - return new TermQuery(names().createIndexNameTerm(indexedValue(value))); + public Query termQuery(Object value, @Nullable QueryParseContext context) { + return new TermQuery(names().createIndexNameTerm(indexedValueForSearch(value))); } @Override - public Filter termFilter(String value, @Nullable QueryParseContext context) { - return new TermFilter(names().createIndexNameTerm(indexedValue(value))); + public Filter termFilter(Object value, @Nullable QueryParseContext context) { + return new TermFilter(names().createIndexNameTerm(indexedValueForSearch(value))); + } + + @Override + public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + return new TermRangeQuery(names.indexName(), + lowerTerm == null ? null : indexedValueForSearch(lowerTerm), + upperTerm == null ? null : indexedValueForSearch(upperTerm), + includeLower, includeUpper); + } + + @Override + public Filter rangeFilter(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + return new TermRangeFilter(names.indexName(), + lowerTerm == null ? null : indexedValueForSearch(lowerTerm), + upperTerm == null ? null : indexedValueForSearch(upperTerm), + includeLower, includeUpper); } @Override public Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions, boolean transpositions) { int edits = FuzzyQuery.floatToEdits(Float.parseFloat(minSim), value.codePointCount(0, value.length())); - return new FuzzyQuery(names.createIndexNameTerm(indexedValue(value)), edits, prefixLength, maxExpansions, transpositions); + return new FuzzyQuery(names.createIndexNameTerm(indexedValueForSearch(value)), edits, prefixLength, maxExpansions, transpositions); } @Override public Query fuzzyQuery(String value, double minSim, int prefixLength, int maxExpansions, boolean transpositions) { int edits = FuzzyQuery.floatToEdits((float) minSim, value.codePointCount(0, value.length())); - return new FuzzyQuery(names.createIndexNameTerm(indexedValue(value)), edits, prefixLength, maxExpansions, transpositions); + return new FuzzyQuery(names.createIndexNameTerm(indexedValueForSearch(value)), edits, prefixLength, maxExpansions, transpositions); } @Override public Query prefixQuery(String value, @Nullable MultiTermQuery.RewriteMethod method, @Nullable QueryParseContext context) { - PrefixQuery query = new PrefixQuery(names().createIndexNameTerm(indexedValue(value))); + PrefixQuery query = new PrefixQuery(names().createIndexNameTerm(indexedValueForSearch(value))); if (method != null) { query.setRewriteMethod(method); } @@ -430,12 +449,12 @@ public abstract class AbstractFieldMapper implements FieldMapper, Mapper { @Override public Filter prefixFilter(String value, @Nullable QueryParseContext context) { - return new PrefixFilter(names().createIndexNameTerm(indexedValue(value))); + return new PrefixFilter(names().createIndexNameTerm(indexedValueForSearch(value))); } @Override public Query regexpQuery(String value, int flags, @Nullable MultiTermQuery.RewriteMethod method, @Nullable QueryParseContext context) { - RegexpQuery query = new RegexpQuery(names().createIndexNameTerm(indexedValue(value)), flags); + RegexpQuery query = new RegexpQuery(names().createIndexNameTerm(indexedValueForSearch(value)), flags); if (method != null) { query.setRewriteMethod(method); } @@ -444,24 +463,7 @@ public abstract class AbstractFieldMapper implements FieldMapper, Mapper { @Override public Filter regexpFilter(String value, int flags, @Nullable QueryParseContext parseContext) { - return new RegexpFilter(names().createIndexNameTerm(indexedValue(value)), flags); - } - - @Override - public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { - // LUCENE 4 UPGRADE: Perhaps indexedValue() should return a BytesRef? - return new TermRangeQuery(names.indexName(), - lowerTerm == null ? null : indexedValue(lowerTerm), - upperTerm == null ? null : indexedValue(upperTerm), - includeLower, includeUpper); - } - - @Override - public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { - return new TermRangeFilter(names.indexName(), - lowerTerm == null ? null : indexedValue(lowerTerm), - upperTerm == null ? null : indexedValue(upperTerm), - includeLower, includeUpper); + return new RegexpFilter(names().createIndexNameTerm(indexedValueForSearch(value)), flags); } @Override diff --git a/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java index cf4828e7efd..be13a07d522 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java @@ -188,14 +188,26 @@ public class BooleanFieldMapper extends AbstractFieldMapper { } @Override - public BytesRef indexedValue(String value) { - if (value == null || value.length() == 0) { + public BytesRef indexedValueForSearch(Object value) { + if (value == null) { return Values.FALSE; } - if (value.length() == 1 && value.charAt(0) == 'F') { + if (value instanceof Boolean) { + return ((Boolean) value) ? Values.TRUE : Values.FALSE; + } + String sValue; + if (value instanceof BytesRef) { + sValue = ((BytesRef) value).utf8ToString(); + } else { + sValue = value.toString(); + } + if (sValue.length() == 0) { return Values.FALSE; } - if (Booleans.parseBoolean(value, false)) { + if (sValue.length() == 1 && sValue.charAt(0) == 'F') { + return Values.FALSE; + } + if (Booleans.parseBoolean(sValue, false)) { return Values.TRUE; } return Values.FALSE; diff --git a/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java index 76e4a504fc8..f1326df26be 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java @@ -147,12 +147,26 @@ public class ByteFieldMapper extends NumberFieldMapper { } @Override - public BytesRef indexedValue(String value) { + public BytesRef indexedValueForSearch(Object value) { BytesRef bytesRef = new BytesRef(); - NumericUtils.intToPrefixCoded(Byte.parseByte(value), precisionStep(), bytesRef); + NumericUtils.intToPrefixCoded(parseValue(value), precisionStep(), bytesRef); return bytesRef; } + private byte parseValue(Object value) { + if (value instanceof Number) { + return ((Number) value).byteValue(); + } + if (value instanceof BytesRef) { + return Byte.parseByte(((BytesRef) value).utf8ToString()); + } + return Byte.parseByte(value.toString()); + } + + private int parseValueAsInt(Object value) { + return parseValue(value); + } + @Override public Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions, boolean transpositions) { byte iValue = Byte.parseByte(value); @@ -179,40 +193,40 @@ public class ByteFieldMapper extends NumberFieldMapper { } @Override - public Query termQuery(String value, @Nullable QueryParseContext context) { - int iValue = Integer.parseInt(value); + public Query termQuery(Object value, @Nullable QueryParseContext context) { + int iValue = parseValue(value); return NumericRangeQuery.newIntRange(names.indexName(), precisionStep, iValue, iValue, true, true); } @Override - public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeQuery.newIntRange(names.indexName(), precisionStep, - lowerTerm == null ? null : Integer.parseInt(lowerTerm), - upperTerm == null ? null : Integer.parseInt(upperTerm), + lowerTerm == null ? null : parseValueAsInt(lowerTerm), + upperTerm == null ? null : parseValueAsInt(upperTerm), includeLower, includeUpper); } @Override - public Filter termFilter(String value, @Nullable QueryParseContext context) { - int iValue = Integer.parseInt(value); + public Filter termFilter(Object value, @Nullable QueryParseContext context) { + int iValue = parseValueAsInt(value); return NumericRangeFilter.newIntRange(names.indexName(), precisionStep, iValue, iValue, true, true); } @Override - public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter rangeFilter(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeFilter.newIntRange(names.indexName(), precisionStep, - lowerTerm == null ? null : Integer.parseInt(lowerTerm), - upperTerm == null ? null : Integer.parseInt(upperTerm), + lowerTerm == null ? null : parseValueAsInt(lowerTerm), + upperTerm == null ? null : parseValueAsInt(upperTerm), includeLower, includeUpper); } @Override - public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter rangeFilter(FieldDataCache fieldDataCache, Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeFieldDataFilter.newByteRange(fieldDataCache, names.indexName(), - lowerTerm == null ? null : Byte.parseByte(lowerTerm), - upperTerm == null ? null : Byte.parseByte(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } diff --git a/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java index e1372f2e457..aeca6185590 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java @@ -215,12 +215,29 @@ public class DateFieldMapper extends NumberFieldMapper { } @Override - public BytesRef indexedValue(String value) { + public BytesRef indexedValueForSearch(Object value) { BytesRef bytesRef = new BytesRef(); - NumericUtils.longToPrefixCoded(dateTimeFormatter.parser().parseMillis(value), precisionStep(), bytesRef); + NumericUtils.longToPrefixCoded(parseValue(value), precisionStep(), bytesRef); return bytesRef; } + private long parseValue(Object value) { + if (value instanceof Number) { + return ((Number) value).longValue(); + } + if (value instanceof BytesRef) { + return dateTimeFormatter.parser().parseMillis(((BytesRef) value).utf8ToString()); + } + return dateTimeFormatter.parser().parseMillis(value.toString()); + } + + private String convertToString(Object value) { + if (value instanceof BytesRef) { + return ((BytesRef) value).utf8ToString(); + } + return value.toString(); + } + @Override public Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions, boolean transpositions) { long iValue = dateMathParser.parse(value, System.currentTimeMillis()); @@ -248,45 +265,45 @@ public class DateFieldMapper extends NumberFieldMapper { } @Override - public Query termQuery(String value, @Nullable QueryParseContext context) { + public Query termQuery(Object value, @Nullable QueryParseContext context) { long now = context == null ? System.currentTimeMillis() : context.nowInMillis(); - long lValue = dateMathParser.parse(value, now); + long lValue = dateMathParser.parse(convertToString(value), now); return NumericRangeQuery.newLongRange(names.indexName(), precisionStep, lValue, lValue, true, true); } @Override - public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter termFilter(Object value, @Nullable QueryParseContext context) { long now = context == null ? System.currentTimeMillis() : context.nowInMillis(); - return NumericRangeQuery.newLongRange(names.indexName(), precisionStep, - lowerTerm == null ? null : dateMathParser.parse(lowerTerm, now), - upperTerm == null ? null : (includeUpper && parseUpperInclusive) ? dateMathParser.parseUpperInclusive(upperTerm, now) : dateMathParser.parse(upperTerm, now), - includeLower, includeUpper); - } - - @Override - public Filter termFilter(String value, @Nullable QueryParseContext context) { - long now = context == null ? System.currentTimeMillis() : context.nowInMillis(); - long lValue = dateMathParser.parse(value, now); + long lValue = dateMathParser.parse(convertToString(value), now); return NumericRangeFilter.newLongRange(names.indexName(), precisionStep, lValue, lValue, true, true); } @Override - public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { long now = context == null ? System.currentTimeMillis() : context.nowInMillis(); - return NumericRangeFilter.newLongRange(names.indexName(), precisionStep, - lowerTerm == null ? null : dateMathParser.parse(lowerTerm, now), - upperTerm == null ? null : (includeUpper && parseUpperInclusive) ? dateMathParser.parseUpperInclusive(upperTerm, now) : dateMathParser.parse(upperTerm, now), + return NumericRangeQuery.newLongRange(names.indexName(), precisionStep, + lowerTerm == null ? null : dateMathParser.parse(convertToString(lowerTerm), now), + upperTerm == null ? null : (includeUpper && parseUpperInclusive) ? dateMathParser.parseUpperInclusive(convertToString(upperTerm), now) : dateMathParser.parse(convertToString(upperTerm), now), includeLower, includeUpper); } @Override - public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter rangeFilter(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + long now = context == null ? System.currentTimeMillis() : context.nowInMillis(); + return NumericRangeFilter.newLongRange(names.indexName(), precisionStep, + lowerTerm == null ? null : dateMathParser.parse(convertToString(lowerTerm), now), + upperTerm == null ? null : (includeUpper && parseUpperInclusive) ? dateMathParser.parseUpperInclusive(convertToString(upperTerm), now) : dateMathParser.parse(convertToString(upperTerm), now), + includeLower, includeUpper); + } + + @Override + public Filter rangeFilter(FieldDataCache fieldDataCache, Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { long now = context == null ? System.currentTimeMillis() : context.nowInMillis(); return NumericRangeFieldDataFilter.newLongRange(fieldDataCache, names.indexName(), - lowerTerm == null ? null : dateMathParser.parse(lowerTerm, now), - upperTerm == null ? null : (includeUpper && parseUpperInclusive) ? dateMathParser.parseUpperInclusive(upperTerm, now) : dateMathParser.parse(upperTerm, now), + lowerTerm == null ? null : dateMathParser.parse(convertToString(lowerTerm), now), + upperTerm == null ? null : (includeUpper && parseUpperInclusive) ? dateMathParser.parseUpperInclusive(convertToString(upperTerm), now) : dateMathParser.parse(convertToString(upperTerm), now), includeLower, includeUpper); } diff --git a/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java index b8eb77af69d..35cb15f6cdf 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java @@ -150,13 +150,23 @@ public class DoubleFieldMapper extends NumberFieldMapper { } @Override - public BytesRef indexedValue(String value) { - long longValue = NumericUtils.doubleToSortableLong(Double.parseDouble(value)); + public BytesRef indexedValueForSearch(Object value) { + long longValue = NumericUtils.doubleToSortableLong(parseValue(value)); BytesRef bytesRef = new BytesRef(); NumericUtils.longToPrefixCoded(longValue, precisionStep(), bytesRef); return bytesRef; } + private double parseValue(Object value) { + if (value instanceof Number) { + return ((Number) value).doubleValue(); + } + if (value instanceof BytesRef) { + return Double.parseDouble(((BytesRef) value).utf8ToString()); + } + return Double.parseDouble(value.toString()); + } + @Override public Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions, boolean transpositions) { double iValue = Double.parseDouble(value); @@ -178,32 +188,32 @@ public class DoubleFieldMapper extends NumberFieldMapper { } @Override - public Query termQuery(String value, @Nullable QueryParseContext context) { - double dValue = Double.parseDouble(value); + public Query termQuery(Object value, @Nullable QueryParseContext context) { + double dValue = parseValue(value); return NumericRangeQuery.newDoubleRange(names.indexName(), precisionStep, dValue, dValue, true, true); } @Override - public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeQuery.newDoubleRange(names.indexName(), precisionStep, - lowerTerm == null ? null : Double.parseDouble(lowerTerm), - upperTerm == null ? null : Double.parseDouble(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } @Override - public Filter termFilter(String value, @Nullable QueryParseContext context) { - double dValue = Double.parseDouble(value); + public Filter termFilter(Object value, @Nullable QueryParseContext context) { + double dValue = parseValue(value); return NumericRangeFilter.newDoubleRange(names.indexName(), precisionStep, dValue, dValue, true, true); } @Override - public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter rangeFilter(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeFilter.newDoubleRange(names.indexName(), precisionStep, - lowerTerm == null ? null : Double.parseDouble(lowerTerm), - upperTerm == null ? null : Double.parseDouble(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } @@ -212,10 +222,10 @@ public class DoubleFieldMapper extends NumberFieldMapper { } @Override - public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter rangeFilter(FieldDataCache fieldDataCache, Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeFieldDataFilter.newDoubleRange(fieldDataCache, names.indexName(), - lowerTerm == null ? null : Double.parseDouble(lowerTerm), - upperTerm == null ? null : Double.parseDouble(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } diff --git a/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java index 33bdc4284ab..1ebc4278bd3 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java @@ -148,13 +148,23 @@ public class FloatFieldMapper extends NumberFieldMapper { } @Override - public BytesRef indexedValue(String value) { - int intValue = NumericUtils.floatToSortableInt(Float.parseFloat(value)); + public BytesRef indexedValueForSearch(Object value) { + int intValue = NumericUtils.floatToSortableInt(parseValue(value)); BytesRef bytesRef = new BytesRef(); NumericUtils.intToPrefixCoded(intValue, precisionStep(), bytesRef); return bytesRef; } + private float parseValue(Object value) { + if (value instanceof Number) { + return ((Number) value).floatValue(); + } + if (value instanceof BytesRef) { + return Float.parseFloat(((BytesRef) value).utf8ToString()); + } + return Float.parseFloat(value.toString()); + } + @Override public Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions, boolean transpositions) { float iValue = Float.parseFloat(value); @@ -176,40 +186,40 @@ public class FloatFieldMapper extends NumberFieldMapper { } @Override - public Query termQuery(String value, @Nullable QueryParseContext context) { - float fValue = Float.parseFloat(value); + public Query termQuery(Object value, @Nullable QueryParseContext context) { + float fValue = parseValue(value); return NumericRangeQuery.newFloatRange(names.indexName(), precisionStep, fValue, fValue, true, true); } @Override - public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeQuery.newFloatRange(names.indexName(), precisionStep, - lowerTerm == null ? null : Float.parseFloat(lowerTerm), - upperTerm == null ? null : Float.parseFloat(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } @Override - public Filter termFilter(String value, @Nullable QueryParseContext context) { - float fValue = Float.parseFloat(value); + public Filter termFilter(Object value, @Nullable QueryParseContext context) { + float fValue = parseValue(value); return NumericRangeFilter.newFloatRange(names.indexName(), precisionStep, fValue, fValue, true, true); } @Override - public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter rangeFilter(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeFilter.newFloatRange(names.indexName(), precisionStep, - lowerTerm == null ? null : Float.parseFloat(lowerTerm), - upperTerm == null ? null : Float.parseFloat(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } @Override - public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter rangeFilter(FieldDataCache fieldDataCache, Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeFieldDataFilter.newFloatRange(fieldDataCache, names.indexName(), - lowerTerm == null ? null : Float.parseFloat(lowerTerm), - upperTerm == null ? null : Float.parseFloat(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } diff --git a/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java index e26b3359382..a3949dd24fa 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java @@ -150,12 +150,22 @@ public class IntegerFieldMapper extends NumberFieldMapper { } @Override - public BytesRef indexedValue(String value) { + public BytesRef indexedValueForSearch(Object value) { BytesRef bytesRef = new BytesRef(); - NumericUtils.intToPrefixCoded(Integer.parseInt(value), precisionStep(), bytesRef); + NumericUtils.intToPrefixCoded(parseValue(value), precisionStep(), bytesRef); return bytesRef; } + private int parseValue(Object value) { + if (value instanceof Number) { + return ((Number) value).intValue(); + } + if (value instanceof BytesRef) { + return Integer.parseInt(((BytesRef) value).utf8ToString()); + } + return Integer.parseInt(value.toString()); + } + @Override public Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions, boolean transpositions) { int iValue = Integer.parseInt(value); @@ -182,40 +192,40 @@ public class IntegerFieldMapper extends NumberFieldMapper { } @Override - public Query termQuery(String value, @Nullable QueryParseContext context) { - int iValue = Integer.parseInt(value); + public Query termQuery(Object value, @Nullable QueryParseContext context) { + int iValue = parseValue(value); return NumericRangeQuery.newIntRange(names.indexName(), precisionStep, iValue, iValue, true, true); } @Override - public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { - return NumericRangeQuery.newIntRange(names.indexName(), precisionStep, - lowerTerm == null ? null : Integer.parseInt(lowerTerm), - upperTerm == null ? null : Integer.parseInt(upperTerm), - includeLower, includeUpper); - } - - @Override - public Filter termFilter(String value, @Nullable QueryParseContext context) { - int iValue = Integer.parseInt(value); + public Filter termFilter(Object value, @Nullable QueryParseContext context) { + int iValue = parseValue(value); return NumericRangeFilter.newIntRange(names.indexName(), precisionStep, iValue, iValue, true, true); } @Override - public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { - return NumericRangeFilter.newIntRange(names.indexName(), precisionStep, - lowerTerm == null ? null : Integer.parseInt(lowerTerm), - upperTerm == null ? null : Integer.parseInt(upperTerm), + public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + return NumericRangeQuery.newIntRange(names.indexName(), precisionStep, + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } @Override - public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter rangeFilter(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + return NumericRangeFilter.newIntRange(names.indexName(), precisionStep, + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), + includeLower, includeUpper); + } + + @Override + public Filter rangeFilter(FieldDataCache fieldDataCache, Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeFieldDataFilter.newIntRange(fieldDataCache, names.indexName(), - lowerTerm == null ? null : Integer.parseInt(lowerTerm), - upperTerm == null ? null : Integer.parseInt(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } diff --git a/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java index c7ed32a6c0f..f6544248645 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java @@ -150,12 +150,22 @@ public class LongFieldMapper extends NumberFieldMapper { } @Override - public BytesRef indexedValue(String value) { + public BytesRef indexedValueForSearch(Object value) { BytesRef bytesRef = new BytesRef(); - NumericUtils.longToPrefixCoded(Long.parseLong(value), precisionStep(), bytesRef); + NumericUtils.longToPrefixCoded(parseValue(value), precisionStep(), bytesRef); return bytesRef; } + private long parseValue(Object value) { + if (value instanceof Number) { + return ((Number) value).longValue(); + } + if (value instanceof BytesRef) { + return Long.parseLong(((BytesRef) value).utf8ToString()); + } + return Long.parseLong(value.toString()); + } + @Override public Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions, boolean transpositions) { long iValue = Long.parseLong(value); @@ -182,40 +192,40 @@ public class LongFieldMapper extends NumberFieldMapper { } @Override - public Query termQuery(String value, @Nullable QueryParseContext context) { - long iValue = Long.parseLong(value); + public Query termQuery(Object value, @Nullable QueryParseContext context) { + long iValue = parseValue(value); return NumericRangeQuery.newLongRange(names.indexName(), precisionStep, iValue, iValue, true, true); } @Override - public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { - return NumericRangeQuery.newLongRange(names.indexName(), precisionStep, - lowerTerm == null ? null : Long.parseLong(lowerTerm), - upperTerm == null ? null : Long.parseLong(upperTerm), - includeLower, includeUpper); - } - - @Override - public Filter termFilter(String value, @Nullable QueryParseContext context) { - long iValue = Long.parseLong(value); + public Filter termFilter(Object value, @Nullable QueryParseContext context) { + long iValue = parseValue(value); return NumericRangeFilter.newLongRange(names.indexName(), precisionStep, iValue, iValue, true, true); } @Override - public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { - return NumericRangeFilter.newLongRange(names.indexName(), precisionStep, - lowerTerm == null ? null : Long.parseLong(lowerTerm), - upperTerm == null ? null : Long.parseLong(upperTerm), + public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + return NumericRangeQuery.newLongRange(names.indexName(), precisionStep, + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } @Override - public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter rangeFilter(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + return NumericRangeFilter.newLongRange(names.indexName(), precisionStep, + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), + includeLower, includeUpper); + } + + @Override + public Filter rangeFilter(FieldDataCache fieldDataCache, Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeFieldDataFilter.newLongRange(fieldDataCache, names.indexName(), - lowerTerm == null ? null : Long.parseLong(lowerTerm), - upperTerm == null ? null : Long.parseLong(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } diff --git a/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java index 44ff722ddb2..d7cf27d99d2 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java @@ -215,35 +215,35 @@ public abstract class NumberFieldMapper extends AbstractFieldM * way to execute it. */ @Override - public Query termQuery(String value, @Nullable QueryParseContext context) { + public Query termQuery(Object value, @Nullable QueryParseContext context) { return rangeQuery(value, value, true, true, context); } + /** + * Numeric field level filter are basically range queries with same value and included. That's the recommended + * way to execute it. + */ + @Override + public Filter termFilter(Object value, @Nullable QueryParseContext context) { + return rangeFilter(value, value, true, true, context); + } + + @Override + public abstract Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context); + + @Override + public abstract Filter rangeFilter(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context); + @Override public abstract Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions, boolean transpositions); @Override public abstract Query fuzzyQuery(String value, double minSim, int prefixLength, int maxExpansions, boolean transpositions); - /** - * Numeric field level filter are basically range queries with same value and included. That's the recommended - * way to execute it. - */ - @Override - public Filter termFilter(String value, @Nullable QueryParseContext context) { - return rangeFilter(value, value, true, true, context); - } - - @Override - public abstract Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context); - - @Override - public abstract Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context); - /** * A range filter based on the field data cache. */ - public abstract Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context); + public abstract Filter rangeFilter(FieldDataCache fieldDataCache, Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context); /** * Override the default behavior (to return the string, and return the actual Number instance). diff --git a/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java index f4268af79f5..dd7ee406598 100644 --- a/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java @@ -150,12 +150,26 @@ public class ShortFieldMapper extends NumberFieldMapper { } @Override - public BytesRef indexedValue(String value) { + public BytesRef indexedValueForSearch(Object value) { BytesRef bytesRef = new BytesRef(); - NumericUtils.intToPrefixCoded(Short.parseShort(value), precisionStep(), bytesRef); + NumericUtils.intToPrefixCoded(parseValue(value), precisionStep(), bytesRef); return bytesRef; } + private short parseValue(Object value) { + if (value instanceof Number) { + return ((Number) value).shortValue(); + } + if (value instanceof BytesRef) { + return Short.parseShort(((BytesRef) value).utf8ToString()); + } + return Short.parseShort(value.toString()); + } + + private int parseValueAsInt(Object value) { + return parseValue(value); + } + @Override public Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions, boolean transpositions) { short iValue = Short.parseShort(value); @@ -182,40 +196,40 @@ public class ShortFieldMapper extends NumberFieldMapper { } @Override - public Query termQuery(String value, @Nullable QueryParseContext context) { - int iValue = Integer.parseInt(value); + public Query termQuery(Object value, @Nullable QueryParseContext context) { + int iValue = parseValueAsInt(value); return NumericRangeQuery.newIntRange(names.indexName(), precisionStep, iValue, iValue, true, true); } @Override - public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeQuery.newIntRange(names.indexName(), precisionStep, - lowerTerm == null ? null : Integer.parseInt(lowerTerm), - upperTerm == null ? null : Integer.parseInt(upperTerm), + lowerTerm == null ? null : parseValueAsInt(lowerTerm), + upperTerm == null ? null : parseValueAsInt(upperTerm), includeLower, includeUpper); } @Override - public Filter termFilter(String value, @Nullable QueryParseContext context) { - int iValue = Integer.parseInt(value); + public Filter termFilter(Object value, @Nullable QueryParseContext context) { + int iValue = parseValueAsInt(value); return NumericRangeFilter.newIntRange(names.indexName(), precisionStep, iValue, iValue, true, true); } @Override - public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter rangeFilter(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeFilter.newIntRange(names.indexName(), precisionStep, - lowerTerm == null ? null : Integer.parseInt(lowerTerm), - upperTerm == null ? null : Integer.parseInt(upperTerm), + lowerTerm == null ? null : parseValueAsInt(lowerTerm), + upperTerm == null ? null : parseValueAsInt(upperTerm), includeLower, includeUpper); } @Override - public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter rangeFilter(FieldDataCache fieldDataCache, Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeFieldDataFilter.newShortRange(fieldDataCache, names.indexName(), - lowerTerm == null ? null : Short.parseShort(lowerTerm), - upperTerm == null ? null : Short.parseShort(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/AllFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/AllFieldMapper.java index c8feead6779..9d67fbd48e7 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/AllFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/AllFieldMapper.java @@ -163,9 +163,8 @@ public class AllFieldMapper extends AbstractFieldMapper implements Interna } @Override - public Query termQuery(String value, QueryParseContext context) { - return queryStringTermQuery(names().createIndexNameTerm(value)); - + public Query termQuery(Object value, QueryParseContext context) { + return queryStringTermQuery(names().createIndexNameTerm(indexedValueForSearch(value))); } @Override diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/BoostFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/BoostFieldMapper.java index eb5e8a108f9..fb5919688a4 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/BoostFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/BoostFieldMapper.java @@ -151,13 +151,23 @@ public class BoostFieldMapper extends NumberFieldMapper implements Intern } @Override - public BytesRef indexedValue(String value) { - int intValue = NumericUtils.floatToSortableInt(Float.parseFloat(value)); + public BytesRef indexedValueForSearch(Object value) { + int intValue = NumericUtils.floatToSortableInt(parseValue(value)); BytesRef bytesRef = new BytesRef(); NumericUtils.intToPrefixCoded(intValue, precisionStep(), bytesRef); return bytesRef; } + private float parseValue(Object value) { + if (value instanceof Number) { + return ((Number) value).floatValue(); + } + if (value instanceof BytesRef) { + return Float.parseFloat(((BytesRef) value).utf8ToString()); + } + return Float.parseFloat(value.toString()); + } + @Override public Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions, boolean transpositions) { float iValue = Float.parseFloat(value); @@ -179,26 +189,26 @@ public class BoostFieldMapper extends NumberFieldMapper implements Intern } @Override - public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeQuery.newFloatRange(names.indexName(), precisionStep, - lowerTerm == null ? null : Float.parseFloat(lowerTerm), - upperTerm == null ? null : Float.parseFloat(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } @Override - public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter rangeFilter(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeFilter.newFloatRange(names.indexName(), precisionStep, - lowerTerm == null ? null : Float.parseFloat(lowerTerm), - upperTerm == null ? null : Float.parseFloat(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } @Override - public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter rangeFilter(FieldDataCache fieldDataCache, Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeFieldDataFilter.newFloatRange(fieldDataCache, names.indexName(), - lowerTerm == null ? null : Float.parseFloat(lowerTerm), - upperTerm == null ? null : Float.parseFloat(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/IdFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/IdFieldMapper.java index 99685ce90ae..a6ea07da41d 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/IdFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/IdFieldMapper.java @@ -26,6 +26,7 @@ import org.apache.lucene.document.FieldType; import org.apache.lucene.index.FieldInfo.IndexOptions; import org.apache.lucene.index.Term; import org.apache.lucene.search.*; +import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Strings; import org.elasticsearch.common.lucene.Lucene; @@ -152,21 +153,26 @@ public class IdFieldMapper extends AbstractFieldMapper implements Intern } @Override - public Query termQuery(String value, @Nullable QueryParseContext context) { + public Query termQuery(Object value, @Nullable QueryParseContext context) { if (fieldType.indexed() || context == null) { return super.termQuery(value, context); } - UidFilter filter = new UidFilter(context.queryTypes(), ImmutableList.of(value)); // no need for constant score filter, since we don't cache the filter, and it always takes deletes into account - return new ConstantScoreQuery(filter); + return new ConstantScoreQuery(termFilter(value, context)); } @Override - public Filter termFilter(String value, @Nullable QueryParseContext context) { + public Filter termFilter(Object value, @Nullable QueryParseContext context) { if (fieldType.indexed() || context == null) { return super.termFilter(value, context); } - return new UidFilter(context.queryTypes(), ImmutableList.of(value)); + BytesRef bytesRef; + if (value instanceof BytesRef) { + bytesRef = (BytesRef) value; + } else { + bytesRef = new BytesRef(value.toString()); + } + return new UidFilter(context.queryTypes(), ImmutableList.of(bytesRef)); } @Override diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java index 30af89e3ad3..de8c8dcaa20 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java @@ -114,11 +114,13 @@ public class ParentFieldMapper extends AbstractFieldMapper implements Inter } private final String type; + private final BytesRef typeAsBytes; protected ParentFieldMapper(String name, String indexName, String type, PostingsFormatProvider postingsFormat) { super(new Names(name, indexName, indexName, name), Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER, postingsFormat, null); this.type = type; + this.typeAsBytes = new BytesRef(type); } public String type() { @@ -199,15 +201,23 @@ public class ParentFieldMapper extends AbstractFieldMapper implements Inter } @Override - public BytesRef indexedValue(String value) { - if (value.indexOf(Uid.DELIMITER) == -1) { - return Uid.createUidAsBytes(type, value); + public BytesRef indexedValueForSearch(Object value) { + if (value instanceof BytesRef) { + BytesRef bytesRef = (BytesRef) value; + if (Uid.hasDelimiter(bytesRef)) { + return bytesRef; + } + return Uid.createUidAsBytes(typeAsBytes, bytesRef); } - return super.indexedValue(value); + String sValue = value.toString(); + if (sValue.indexOf(Uid.DELIMITER) == -1) { + return Uid.createUidAsBytes(type, sValue); + } + return super.indexedValueForSearch(value); } @Override - public Query termQuery(String value, @Nullable QueryParseContext context) { + public Query termQuery(Object value, @Nullable QueryParseContext context) { if (context == null) { return super.termQuery(value, context); } @@ -215,15 +225,21 @@ public class ParentFieldMapper extends AbstractFieldMapper implements Inter } @Override - public Filter termFilter(String value, @Nullable QueryParseContext context) { + public Filter termFilter(Object value, @Nullable QueryParseContext context) { if (context == null) { return super.termFilter(value, context); } + BytesRef bValue; + if (value instanceof BytesRef) { + bValue = (BytesRef) value; + } else { + bValue = new BytesRef(value.toString()); + } // we use all types, cause we don't know if its exact or not... Term[] typesTerms = new Term[context.mapperService().types().size()]; int i = 0; for (String type : context.mapperService().types()) { - typesTerms[i++] = names.createIndexNameTerm(Uid.createUid(type, value)); + typesTerms[i++] = names.createIndexNameTerm(Uid.createUidAsBytes(type, bValue)); } return new XTermsFilter(typesTerms); } diff --git a/src/main/java/org/elasticsearch/index/mapper/internal/TypeFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/internal/TypeFieldMapper.java index ae99001a2db..39f9e30dc6b 100644 --- a/src/main/java/org/elasticsearch/index/mapper/internal/TypeFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/internal/TypeFieldMapper.java @@ -26,6 +26,7 @@ import org.apache.lucene.index.Term; import org.apache.lucene.search.Filter; import org.apache.lucene.search.PrefixFilter; import org.apache.lucene.search.Query; +import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.lucene.search.TermFilter; @@ -123,16 +124,22 @@ public class TypeFieldMapper extends AbstractFieldMapper implements Inte } @Override - public Filter termFilter(String value, @Nullable QueryParseContext context) { - if (!fieldType.indexed()) { - return new PrefixFilter(new Term(UidFieldMapper.NAME, Uid.typePrefix(value))); - } - return new TermFilter(names().createIndexNameTerm(value)); + public Query termQuery(Object value, @Nullable QueryParseContext context) { + return new XConstantScoreQuery(context.cacheFilter(termFilter(value, context), null)); } @Override - public Query termQuery(String value, @Nullable QueryParseContext context) { - return new XConstantScoreQuery(context.cacheFilter(termFilter(value, context), null)); + public Filter termFilter(Object value, @Nullable QueryParseContext context) { + BytesRef bytesRef; + if (value instanceof BytesRef) { + bytesRef = (BytesRef) value; + } else { + bytesRef = new BytesRef(value.toString()); + } + if (!fieldType.indexed()) { + return new PrefixFilter(new Term(UidFieldMapper.NAME, Uid.typePrefixAsBytes(bytesRef))); + } + return new TermFilter(names().createIndexNameTerm(bytesRef)); } @Override diff --git a/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java b/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java index b968897dcbf..44d0d5b7a7f 100644 --- a/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java +++ b/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java @@ -185,12 +185,22 @@ public class IpFieldMapper extends NumberFieldMapper { } @Override - public BytesRef indexedValue(String value) { + public BytesRef indexedValueForSearch(Object value) { BytesRef bytesRef = new BytesRef(); - NumericUtils.longToPrefixCoded(ipToLong(value), precisionStep(), bytesRef); + NumericUtils.longToPrefixCoded(parseValue(value), precisionStep(), bytesRef); return bytesRef; } + private long parseValue(Object value) { + if (value instanceof Number) { + return ((Number) value).longValue(); + } + if (value instanceof BytesRef) { + return ipToLong(((BytesRef) value).utf8ToString()); + } + return ipToLong(value.toString()); + } + @Override public Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions, boolean transpositions) { long iValue = ipToLong(value); @@ -214,30 +224,30 @@ public class IpFieldMapper extends NumberFieldMapper { public Query fuzzyQuery(String value, double minSim, int prefixLength, int maxExpansions, boolean transpositions) { // Lucene 4 Upgrade: It's surprising this uses FuzzyQuery instead of NumericRangeQuery int edits = FuzzyQuery.floatToEdits((float) minSim, value.codePointCount(0, value.length())); - return new FuzzyQuery(names.createIndexNameTerm(indexedValue(value)), edits, prefixLength, maxExpansions, transpositions); + return new FuzzyQuery(names.createIndexNameTerm(indexedValueForSearch(value)), edits, prefixLength, maxExpansions, transpositions); } @Override - public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeQuery.newLongRange(names.indexName(), precisionStep, - lowerTerm == null ? null : ipToLong(lowerTerm), - upperTerm == null ? null : ipToLong(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } @Override - public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter rangeFilter(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeFilter.newLongRange(names.indexName(), precisionStep, - lowerTerm == null ? null : ipToLong(lowerTerm), - upperTerm == null ? null : ipToLong(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } @Override - public Filter rangeFilter(FieldDataCache fieldDataCache, String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { + public Filter rangeFilter(FieldDataCache fieldDataCache, Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) { return NumericRangeFieldDataFilter.newLongRange(fieldDataCache, names.indexName(), - lowerTerm == null ? null : ipToLong(lowerTerm), - upperTerm == null ? null : ipToLong(upperTerm), + lowerTerm == null ? null : parseValue(lowerTerm), + upperTerm == null ? null : parseValue(upperTerm), includeLower, includeUpper); } diff --git a/src/main/java/org/elasticsearch/index/query/IdsFilterParser.java b/src/main/java/org/elasticsearch/index/query/IdsFilterParser.java index a3231f1df5a..6940938a8b1 100644 --- a/src/main/java/org/elasticsearch/index/query/IdsFilterParser.java +++ b/src/main/java/org/elasticsearch/index/query/IdsFilterParser.java @@ -22,6 +22,7 @@ package org.elasticsearch.index.query; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import org.apache.lucene.search.Filter; +import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.search.UidFilter; @@ -48,7 +49,7 @@ public class IdsFilterParser implements FilterParser { public Filter parse(QueryParseContext parseContext) throws IOException, QueryParsingException { XContentParser parser = parseContext.parser(); - List ids = new ArrayList(); + List ids = new ArrayList(); Collection types = null; String filterName = null; String currentFieldName = null; @@ -59,7 +60,7 @@ public class IdsFilterParser implements FilterParser { } else if (token == XContentParser.Token.START_ARRAY) { if ("values".equals(currentFieldName)) { while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { - String value = parser.textOrNull(); + BytesRef value = parser.bytesOrNull(); if (value == null) { throw new QueryParsingException(parseContext.index(), "No value specified for term filter"); } diff --git a/src/main/java/org/elasticsearch/index/query/IdsQueryParser.java b/src/main/java/org/elasticsearch/index/query/IdsQueryParser.java index 3230c79e316..0a2db615109 100644 --- a/src/main/java/org/elasticsearch/index/query/IdsQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/IdsQueryParser.java @@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.Query; +import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.search.UidFilter; @@ -52,7 +53,7 @@ public class IdsQueryParser implements QueryParser { public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException { XContentParser parser = parseContext.parser(); - List ids = new ArrayList(); + List ids = new ArrayList(); Collection types = null; String currentFieldName = null; float boost = 1.0f; @@ -63,7 +64,7 @@ public class IdsQueryParser implements QueryParser { } else if (token == XContentParser.Token.START_ARRAY) { if ("values".equals(currentFieldName)) { while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { - String value = parser.textOrNull(); + BytesRef value = parser.bytesOrNull(); if (value == null) { throw new QueryParsingException(parseContext.index(), "No value specified for term filter"); } diff --git a/src/main/java/org/elasticsearch/index/query/SpanTermQueryParser.java b/src/main/java/org/elasticsearch/index/query/SpanTermQueryParser.java index 4766c35c078..f819c6dc938 100644 --- a/src/main/java/org/elasticsearch/index/query/SpanTermQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/SpanTermQueryParser.java @@ -96,7 +96,7 @@ public class SpanTermQueryParser implements QueryParser { if (smartNameFieldMappers != null) { if (smartNameFieldMappers.hasMapper()) { fieldName = smartNameFieldMappers.mapper().names().indexName(); - valueBytes = smartNameFieldMappers.mapper().indexedValue(value); + valueBytes = smartNameFieldMappers.mapper().indexedValueForSearch(value); } } if (valueBytes == null) { diff --git a/src/main/java/org/elasticsearch/index/query/TermsFilterParser.java b/src/main/java/org/elasticsearch/index/query/TermsFilterParser.java index 5021f03c72c..9e144b74322 100644 --- a/src/main/java/org/elasticsearch/index/query/TermsFilterParser.java +++ b/src/main/java/org/elasticsearch/index/query/TermsFilterParser.java @@ -116,7 +116,7 @@ public class TermsFilterParser implements FilterParser { Term[] filterTerms = new Term[terms.size()]; if (fieldMapper != null) { for (int i = 0; i < filterTerms.length; i++) { - filterTerms[i] = fieldMapper.names().createIndexNameTerm(fieldMapper.indexedValue(terms.get(i))); + filterTerms[i] = fieldMapper.names().createIndexNameTerm(fieldMapper.indexedValueForSearch(terms.get(i))); } } else { for (int i = 0; i < filterTerms.length; i++) { diff --git a/src/main/java/org/elasticsearch/index/query/WildcardQueryParser.java b/src/main/java/org/elasticsearch/index/query/WildcardQueryParser.java index 8baf11947da..31d6a8e2d33 100644 --- a/src/main/java/org/elasticsearch/index/query/WildcardQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/WildcardQueryParser.java @@ -95,7 +95,7 @@ public class WildcardQueryParser implements QueryParser { MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName); if (smartNameFieldMappers != null && smartNameFieldMappers.hasMapper()) { fieldName = smartNameFieldMappers.mapper().names().indexName(); - valueBytes = smartNameFieldMappers.mapper().indexedValue(value); + valueBytes = smartNameFieldMappers.mapper().indexedValueForSearch(value); } else { valueBytes = new BytesRef(value); } diff --git a/src/main/java/org/elasticsearch/index/search/UidFilter.java b/src/main/java/org/elasticsearch/index/search/UidFilter.java index bdf712acc72..4212a2c7aa0 100644 --- a/src/main/java/org/elasticsearch/index/search/UidFilter.java +++ b/src/main/java/org/elasticsearch/index/search/UidFilter.java @@ -23,6 +23,7 @@ import org.apache.lucene.index.*; import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.Filter; import org.apache.lucene.util.Bits; +import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.FixedBitSet; import org.elasticsearch.index.mapper.Uid; import org.elasticsearch.index.mapper.internal.UidFieldMapper; @@ -37,12 +38,12 @@ public class UidFilter extends Filter { final Term[] uids; - public UidFilter(Collection types, List ids) { + public UidFilter(Collection types, List ids) { this.uids = new Term[types.size() * ids.size()]; int i = 0; for (String type : types) { - for (String id : ids) { - uids[i++] = new Term(UidFieldMapper.NAME, Uid.createUid(type, id)); + for (BytesRef id : ids) { + uids[i++] = new Term(UidFieldMapper.NAME, Uid.createUidAsBytes(type, id)); } } if (this.uids.length > 1) {