work on terms api to work properly with number types

This commit is contained in:
kimchy 2010-03-21 22:38:51 +02:00
parent a039a6cc38
commit bc03d89c00
13 changed files with 146 additions and 10 deletions

View File

@ -20,6 +20,7 @@
package org.elasticsearch.action.terms; package org.elasticsearch.action.terms;
import org.elasticsearch.ElasticSearchIllegalArgumentException; import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.support.broadcast.BroadcastOperationRequest; import org.elasticsearch.action.support.broadcast.BroadcastOperationRequest;
import org.elasticsearch.index.mapper.AllFieldMapper; import org.elasticsearch.index.mapper.AllFieldMapper;
import org.elasticsearch.util.io.stream.StreamInput; import org.elasticsearch.util.io.stream.StreamInput;
@ -141,6 +142,14 @@ public class TermsRequest extends BroadcastOperationRequest {
super(indices, null); super(indices, null);
} }
@Override public ActionRequestValidationException validate() {
ActionRequestValidationException validationException = super.validate();
if (fields == null || fields.length == 0) {
fields = DEFAULT_FIELDS;
}
return validationException;
}
/** /**
* The fields within each document which terms will be iterated over and returned with the * The fields within each document which terms will be iterated over and returned with the
* document frequencies. * document frequencies.

View File

@ -196,6 +196,18 @@ public class TransportTermsAction extends TransportBroadcastOperationAction<Term
if (term == null || indexFieldName != term.field()) { // StirngHelper.intern if (term == null || indexFieldName != term.field()) { // StirngHelper.intern
break; break;
} }
// convert to actual term text
if (fieldMapper != null && fieldMapper.requiresStringToStringConversion()) {
// valueAsString returns null indicating that this is not interesting
term = term.createTerm(fieldMapper.valueAsString(term.text()));
// if we need to break on this term enumeration, bail
if (fieldMapper.shouldBreakTermEnumeration(term.text())) {
break;
}
if (term.text() == null) {
continue;
}
}
// does it match on the prefix? // does it match on the prefix?
if (request.prefix() != null && !term.text().startsWith(request.prefix())) { if (request.prefix() != null && !term.text().startsWith(request.prefix())) {
break; break;
@ -240,6 +252,18 @@ public class TransportTermsAction extends TransportBroadcastOperationAction<Term
if (term == null || indexFieldName != term.field()) { // StirngHelper.intern if (term == null || indexFieldName != term.field()) { // StirngHelper.intern
break; break;
} }
// convert to actual term text
if (fieldMapper != null && fieldMapper.requiresStringToStringConversion()) {
// valueAsString returns null indicating that this is not interesting
term = term.createTerm(fieldMapper.valueAsString(term.text()));
// if we need to break on this term enumeration, bail
if (fieldMapper.shouldBreakTermEnumeration(term.text())) {
break;
}
if (term.text() == null) {
continue;
}
}
// does it match on the prefix? // does it match on the prefix?
if (request.prefix() != null && !term.text().startsWith(request.prefix())) { if (request.prefix() != null && !term.text().startsWith(request.prefix())) {
break; break;

View File

@ -20,6 +20,7 @@
package org.elasticsearch.cluster.node; package org.elasticsearch.cluster.node;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import org.apache.lucene.util.StringHelper;
import org.elasticsearch.util.io.stream.StreamInput; import org.elasticsearch.util.io.stream.StreamInput;
import org.elasticsearch.util.io.stream.StreamOutput; import org.elasticsearch.util.io.stream.StreamOutput;
import org.elasticsearch.util.io.stream.Streamable; import org.elasticsearch.util.io.stream.Streamable;
@ -36,7 +37,7 @@ public class Node implements Streamable, Serializable {
public static final ImmutableList<Node> EMPTY_LIST = ImmutableList.of(); public static final ImmutableList<Node> EMPTY_LIST = ImmutableList.of();
private String nodeName = ""; private String nodeName = StringHelper.intern("");
private String nodeId; private String nodeId;
@ -52,12 +53,13 @@ public class Node implements Streamable, Serializable {
} }
public Node(String nodeName, boolean dataNode, String nodeId, TransportAddress address) { public Node(String nodeName, boolean dataNode, String nodeId, TransportAddress address) {
this.nodeName = nodeName; if (nodeName == null) {
this.dataNode = dataNode; this.nodeName = StringHelper.intern("");
if (this.nodeName == null) { } else {
this.nodeName = ""; this.nodeName = StringHelper.intern(nodeName);
} }
this.nodeId = nodeId; this.dataNode = dataNode;
this.nodeId = StringHelper.intern(nodeId);
this.address = address; this.address = address;
} }
@ -96,9 +98,9 @@ public class Node implements Streamable, Serializable {
} }
@Override public void readFrom(StreamInput in) throws IOException { @Override public void readFrom(StreamInput in) throws IOException {
nodeName = in.readUTF(); nodeName = StringHelper.intern(in.readUTF());
dataNode = in.readBoolean(); dataNode = in.readBoolean();
nodeId = in.readUTF(); nodeId = StringHelper.intern(in.readUTF());
address = TransportAddressSerializers.addressFromStream(in); address = TransportAddressSerializers.addressFromStream(in);
} }

View File

@ -19,6 +19,7 @@
package org.elasticsearch.index; package org.elasticsearch.index;
import org.apache.lucene.util.StringHelper;
import org.elasticsearch.util.concurrent.Immutable; import org.elasticsearch.util.concurrent.Immutable;
import org.elasticsearch.util.io.stream.StreamInput; import org.elasticsearch.util.io.stream.StreamInput;
import org.elasticsearch.util.io.stream.StreamOutput; import org.elasticsearch.util.io.stream.StreamOutput;
@ -40,7 +41,7 @@ public class Index implements Serializable, Streamable {
} }
public Index(String name) { public Index(String name) {
this.name = name; this.name = StringHelper.intern(name);
} }
public String name() { public String name() {
@ -73,7 +74,7 @@ public class Index implements Serializable, Streamable {
} }
@Override public void readFrom(StreamInput in) throws IOException { @Override public void readFrom(StreamInput in) throws IOException {
name = in.readUTF(); name = StringHelper.intern(in.readUTF());
} }
@Override public void writeTo(StreamOutput out) throws IOException { @Override public void writeTo(StreamOutput out) throws IOException {

View File

@ -128,6 +128,25 @@ public interface FieldMapper<T> {
*/ */
String valueAsString(Fieldable field); String valueAsString(Fieldable field);
/**
* Returns <tt>true</tt> if {@link #valueAsString(String)} is required to convert
* from text value to text value.
*/
boolean requiresStringToStringConversion();
/**
* Converts from the internal/indexed (term) text to the actual string representation.
* Can return <tt>null</tt> indicating that this is "uninteresting" value (for example, with
* numbers). Useful for example when enumerating terms. See {@link #shouldBreakTermEnumeration(String)}.
*/
String valueAsString(String text);
/**
* Return <tt>true</tt> if this term value indicates breaking out of term enumeration on this
* field. The term text passed is the one returned from {@link #valueAsString(String)}.
*/
boolean shouldBreakTermEnumeration(String text);
/** /**
* Returns the indexed value. * Returns the indexed value.
*/ */

View File

@ -110,6 +110,14 @@ public class JsonBoostFieldMapper extends JsonNumberFieldMapper<Float> implement
return NumericUtils.floatToPrefixCoded(value); return NumericUtils.floatToPrefixCoded(value);
} }
@Override public String valueAsString(String text) {
final int shift = text.charAt(0) - NumericUtils.SHIFT_START_INT;
if (shift > 0 && shift <= 31) {
return null;
}
return Float.toString(NumericUtils.prefixCodedToFloat(text));
}
@Override public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { @Override public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) {
return NumericRangeQuery.newFloatRange(names.indexName(), precisionStep, return NumericRangeQuery.newFloatRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Float.parseFloat(lowerTerm), lowerTerm == null ? null : Float.parseFloat(lowerTerm),

View File

@ -115,6 +115,14 @@ public class JsonDateFieldMapper extends JsonNumberFieldMapper<Long> {
return NumericUtils.longToPrefixCoded(value); return NumericUtils.longToPrefixCoded(value);
} }
@Override public String valueAsString(String text) {
final int shift = text.charAt(0) - NumericUtils.SHIFT_START_LONG;
if (shift > 0 && shift <= 63) {
return null;
}
return dateTimeFormatter.printer().print(NumericUtils.prefixCodedToLong(text));
}
@Override public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { @Override public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) {
return NumericRangeQuery.newLongRange(names.indexName(), precisionStep, return NumericRangeQuery.newLongRange(names.indexName(), precisionStep,
lowerTerm == null ? null : dateTimeFormatter.parser().parseMillis(lowerTerm), lowerTerm == null ? null : dateTimeFormatter.parser().parseMillis(lowerTerm),

View File

@ -99,6 +99,14 @@ public class JsonDoubleFieldMapper extends JsonNumberFieldMapper<Double> {
return NumericUtils.doubleToPrefixCoded(value); return NumericUtils.doubleToPrefixCoded(value);
} }
@Override public String valueAsString(String text) {
final int shift = text.charAt(0) - NumericUtils.SHIFT_START_LONG;
if (shift > 0 && shift <= 63) {
return null;
}
return Double.toString(NumericUtils.prefixCodedToDouble(text));
}
@Override public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { @Override public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) {
return NumericRangeQuery.newDoubleRange(names.indexName(), precisionStep, return NumericRangeQuery.newDoubleRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Double.parseDouble(lowerTerm), lowerTerm == null ? null : Double.parseDouble(lowerTerm),

View File

@ -292,6 +292,27 @@ public abstract class JsonFieldMapper<T> implements FieldMapper<T>, JsonMapper {
return valueAsString(field); return valueAsString(field);
} }
/**
* Default base does not require stringToString conversion.
*/
@Override public boolean requiresStringToStringConversion() {
return false;
}
/**
* Simply returns the same string.
*/
@Override public String valueAsString(String text) {
return text;
}
/**
* Never break on this term enumeration value.
*/
@Override public boolean shouldBreakTermEnumeration(String text) {
return false;
}
@Override public String indexedValue(String value) { @Override public String indexedValue(String value) {
return value; return value;
} }

View File

@ -99,6 +99,14 @@ public class JsonFloatFieldMapper extends JsonNumberFieldMapper<Float> {
return NumericUtils.floatToPrefixCoded(value); return NumericUtils.floatToPrefixCoded(value);
} }
@Override public String valueAsString(String text) {
final int shift = text.charAt(0) - NumericUtils.SHIFT_START_INT;
if (shift > 0 && shift <= 31) {
return null;
}
return Float.toString(NumericUtils.prefixCodedToFloat(text));
}
@Override public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { @Override public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) {
return NumericRangeQuery.newFloatRange(names.indexName(), precisionStep, return NumericRangeQuery.newFloatRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Float.parseFloat(lowerTerm), lowerTerm == null ? null : Float.parseFloat(lowerTerm),

View File

@ -98,6 +98,10 @@ public class JsonIntegerFieldMapper extends JsonNumberFieldMapper<Integer> {
return NumericUtils.intToPrefixCoded(value); return NumericUtils.intToPrefixCoded(value);
} }
@Override public String valueAsString(String text) {
return Integer.toString(NumericUtils.prefixCodedToInt(text));
}
@Override public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { @Override public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) {
return NumericRangeQuery.newIntRange(names.indexName(), precisionStep, return NumericRangeQuery.newIntRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Integer.parseInt(lowerTerm), lowerTerm == null ? null : Integer.parseInt(lowerTerm),

View File

@ -98,6 +98,14 @@ public class JsonLongFieldMapper extends JsonNumberFieldMapper<Long> {
return NumericUtils.longToPrefixCoded(value); return NumericUtils.longToPrefixCoded(value);
} }
@Override public String valueAsString(String text) {
final int shift = text.charAt(0) - NumericUtils.SHIFT_START_LONG;
if (shift > 0 && shift <= 63) {
return null;
}
return Long.toString(NumericUtils.prefixCodedToLong(text));
}
@Override public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) { @Override public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) {
return NumericRangeQuery.newLongRange(names.indexName(), precisionStep, return NumericRangeQuery.newLongRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Long.parseLong(lowerTerm), lowerTerm == null ? null : Long.parseLong(lowerTerm),

View File

@ -129,6 +129,22 @@ public abstract class JsonNumberFieldMapper<T extends Number> extends JsonFieldM
return value(field).toString(); return value(field).toString();
} }
/**
* Numbers require string conversion.
*/
@Override public boolean requiresStringToStringConversion() {
return true;
}
@Override public abstract String valueAsString(String text);
/**
* Breaks on this text if its <tt>null</tt>.
*/
@Override public boolean shouldBreakTermEnumeration(String text) {
return text == null;
}
@Override protected void doJsonBody(JsonBuilder builder) throws IOException { @Override protected void doJsonBody(JsonBuilder builder) throws IOException {
super.doJsonBody(builder); super.doJsonBody(builder);
builder.field("precisionStep", precisionStep); builder.field("precisionStep", precisionStep);