Skip to content

Commit

Permalink
Mapping: Support for short type, closes #84.
Browse files Browse the repository at this point in the history
  • Loading branch information
kimchy committed Mar 23, 2010
1 parent 0a2de7c commit 621d222
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ private void parseProperties(JsonObjectMapper.Builder objBuilder, ObjectNode pro
objBuilder.add(parseString(propName, (ObjectNode) propNode));
} else if (type.equals(JsonDateFieldMapper.JSON_TYPE)) {
objBuilder.add(parseDate(propName, (ObjectNode) propNode));
} else if (type.equals(JsonShortFieldMapper.JSON_TYPE)) {
objBuilder.add(parseShort(propName, (ObjectNode) propNode));
} else if (type.equals(JsonIntegerFieldMapper.JSON_TYPE)) {
objBuilder.add(parseInteger(propName, (ObjectNode) propNode));
} else if (type.equals(JsonLongFieldMapper.JSON_TYPE)) {
Expand Down Expand Up @@ -376,6 +378,20 @@ private JsonDateFieldMapper.Builder parseDate(String name, ObjectNode dateNode)
return builder;
}

private JsonShortFieldMapper.Builder parseShort(String name, ObjectNode integerNode) {
JsonShortFieldMapper.Builder builder = shortField(name);
parseNumberField(builder, name, integerNode);
for (Iterator<Map.Entry<String, JsonNode>> propsIt = integerNode.getFields(); propsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = propsIt.next();
String propName = entry.getKey();
JsonNode propNode = entry.getValue();
if (propName.equals("nullValue")) {
builder.nullValue(nodeShortValue(propNode));
}
}
return builder;
}


private JsonIntegerFieldMapper.Builder parseInteger(String name, ObjectNode integerNode) {
JsonIntegerFieldMapper.Builder builder = integerField(name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ public static JsonDateFieldMapper.Builder dateField(String name) {
return new JsonDateFieldMapper.Builder(name);
}

public static JsonShortFieldMapper.Builder shortField(String name) {
return new JsonShortFieldMapper.Builder(name);
}

public static JsonIntegerFieldMapper.Builder integerField(String name) {
return new JsonIntegerFieldMapper.Builder(name);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/*
* Licensed to Elastic Search and Shay Banon under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Elastic Search licenses this
* file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.elasticsearch.index.mapper.json;

import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.search.*;
import org.apache.lucene.util.NumericUtils;
import org.codehaus.jackson.JsonToken;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.analysis.NumericIntegerAnalyzer;
import org.elasticsearch.util.Numbers;
import org.elasticsearch.util.json.JsonBuilder;

import java.io.IOException;

/**
* @author kimchy (shay.banon)
*/
public class JsonShortFieldMapper extends JsonNumberFieldMapper<Short> {

public static final String JSON_TYPE = "short";

public static class Defaults extends JsonNumberFieldMapper.Defaults {
public static final Short NULL_VALUE = null;
}

public static class Builder extends JsonNumberFieldMapper.Builder<Builder, JsonShortFieldMapper> {

protected Short nullValue = Defaults.NULL_VALUE;

public Builder(String name) {
super(name);
builder = this;
}

public Builder nullValue(short nullValue) {
this.nullValue = nullValue;
return this;
}

@Override public JsonShortFieldMapper build(BuilderContext context) {
JsonShortFieldMapper fieldMapper = new JsonShortFieldMapper(buildNames(context),
precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions, nullValue);
fieldMapper.includeInAll(includeInAll);
return fieldMapper;
}
}

private final Short nullValue;

private final String nullValueAsString;

protected JsonShortFieldMapper(Names names, int precisionStep, Field.Index index, Field.Store store,
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
Short nullValue) {
super(names, precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions,
new NamedAnalyzer("_short/" + precisionStep, new NumericIntegerAnalyzer(precisionStep)),
new NamedAnalyzer("_short/max", new NumericIntegerAnalyzer(Integer.MAX_VALUE)));
this.nullValue = nullValue;
this.nullValueAsString = nullValue == null ? null : nullValue.toString();
}

@Override protected int maxPrecisionStep() {
return 32;
}

@Override public Short value(Fieldable field) {
byte[] value = field.getBinaryValue();
if (value == null) {
return Short.MIN_VALUE;
}
return Numbers.bytesToShort(value);
}

@Override public String indexedValue(String value) {
return indexedValue(Short.parseShort(value));
}

@Override public String indexedValue(Short value) {
return NumericUtils.intToPrefixCoded(value);
}

@Override public Object valueFromTerm(String term) {
final int shift = term.charAt(0) - NumericUtils.SHIFT_START_INT;
if (shift > 0 && shift <= 31) {
return null;
}
return NumericUtils.prefixCodedToInt(term);
}

@Override public Object valueFromString(String text) {
return Short.parseShort(text);
}

@Override public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) {
return NumericRangeQuery.newIntRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Integer.parseInt(lowerTerm),
upperTerm == null ? null : Integer.parseInt(upperTerm),
includeLower, includeUpper);
}

@Override public Filter rangeFilter(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) {
return NumericRangeFilter.newIntRange(names.indexName(), precisionStep,
lowerTerm == null ? null : Integer.parseInt(lowerTerm),
upperTerm == null ? null : Integer.parseInt(upperTerm),
includeLower, includeUpper);
}

@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
int value;
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_NULL) {
if (nullValue == null) {
return null;
}
value = nullValue;
if (includeInAll == null || includeInAll) {
jsonContext.allEntries().addText(names.fullName(), nullValueAsString, boost);
}
} else {
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_STRING) {
value = Integer.parseInt(jsonContext.jp().getText());
} else {
value = jsonContext.jp().getIntValue();
}
if (includeInAll == null || includeInAll) {
jsonContext.allEntries().addText(names.fullName(), jsonContext.jp().getText(), boost);
}
}
Field field = null;
if (stored()) {
field = new Field(names.indexName(), Numbers.shortToBytes(value), store);
if (indexed()) {
field.setTokenStream(popCachedStream(precisionStep).setIntValue(value));
}
} else if (indexed()) {
field = new Field(names.indexName(), popCachedStream(precisionStep).setIntValue(value));
}
return field;
}

@Override public int sortType() {
return SortField.SHORT;
}

@Override protected String jsonType() {
return JSON_TYPE;
}

@Override protected void doJsonBody(JsonBuilder builder) throws IOException {
super.doJsonBody(builder);
if (nullValue != null) {
builder.field("nullValue", nullValue);
}
if (includeInAll != null) {
builder.field("includeInAll", includeInAll);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ private Numbers() {

}

/**
* Converts a byte array to an short.
*
* @param arr The byte array to convert to an short
* @return The int converted
*/
public static short bytesToShort(byte[] arr) {
return (short) (((arr[2] & 0xff) << 8) | (arr[3] & 0xff));
}

/**
* Converts a byte array to an int.
*
Expand Down Expand Up @@ -87,6 +97,19 @@ public static byte[] intToBytes(int val) {
return arr;
}

/**
* Converts an int to a byte array.
*
* @param val The int to convert to a byte array
* @return The byte array converted
*/
public static byte[] shortToBytes(int val) {
byte[] arr = new byte[2];
arr[2] = (byte) (val >>> 8);
arr[3] = (byte) (val);
return arr;
}

/**
* Converts a long to a byte array.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ public static int nodeIntegerValue(JsonNode node) {
return Integer.parseInt(value);
}

public static short nodeShortValue(JsonNode node) {
if (node.isNumber()) {
return node.getNumberValue().shortValue();
}
String value = node.getTextValue();
return Short.parseShort(value);
}

public static long nodeLongValue(JsonNode node) {
if (node.isNumber()) {
return node.getNumberValue().longValue();
Expand Down

0 comments on commit 621d222

Please sign in to comment.