Mappings: Refactor core index/query time properties into FieldType
Mappers are currently used at both index and query time for deciding how to "use" a field. For #8871, we need the index wide view of mappings to have a unified set of settings for each field of a given name within the index. This change moves all the current settings (and methods defining query time behavior) into subclasses of FieldType. In a future PR, this will allow storing the field type at the index level, instead of mappers (which can still have settings that differ per document type). The change is quite large (I'm sorry). I could not see a way to migrate to this in a more piecemeal way. I did leave out cutting over callers of the query methods to using the field type, as that can be done in a follow up.
This commit is contained in:
parent
29fbcd225b
commit
1f2c42fd0b
|
@ -260,7 +260,7 @@ public class MapperQueryParser extends QueryParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
query = super.getFieldQuery(currentMapper.names().indexName(), queryText, quoted);
|
query = super.getFieldQuery(currentMapper.fieldType().names().indexName(), queryText, quoted);
|
||||||
}
|
}
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
@ -372,7 +372,7 @@ public class MapperQueryParser extends QueryParser {
|
||||||
Query rangeQuery;
|
Query rangeQuery;
|
||||||
if (currentMapper instanceof DateFieldMapper && settings.timeZone() != null) {
|
if (currentMapper instanceof DateFieldMapper && settings.timeZone() != null) {
|
||||||
DateFieldMapper dateFieldMapper = (DateFieldMapper) this.currentMapper;
|
DateFieldMapper dateFieldMapper = (DateFieldMapper) this.currentMapper;
|
||||||
rangeQuery = dateFieldMapper.rangeQuery(part1, part2, startInclusive, endInclusive, settings.timeZone(), null, parseContext);
|
rangeQuery = dateFieldMapper.fieldType().rangeQuery(part1, part2, startInclusive, endInclusive, settings.timeZone(), null, parseContext);
|
||||||
} else {
|
} else {
|
||||||
rangeQuery = currentMapper.rangeQuery(part1, part2, startInclusive, endInclusive, parseContext);
|
rangeQuery = currentMapper.rangeQuery(part1, part2, startInclusive, endInclusive, parseContext);
|
||||||
}
|
}
|
||||||
|
@ -508,7 +508,7 @@ public class MapperQueryParser extends QueryParser {
|
||||||
query = currentMapper.prefixQuery(termStr, multiTermRewriteMethod, parseContext);
|
query = currentMapper.prefixQuery(termStr, multiTermRewriteMethod, parseContext);
|
||||||
}
|
}
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
query = getPossiblyAnalyzedPrefixQuery(currentMapper.names().indexName(), termStr);
|
query = getPossiblyAnalyzedPrefixQuery(currentMapper.fieldType().names().indexName(), termStr);
|
||||||
}
|
}
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
@ -644,7 +644,7 @@ public class MapperQueryParser extends QueryParser {
|
||||||
if (!forcedAnalyzer) {
|
if (!forcedAnalyzer) {
|
||||||
setAnalyzer(parseContext.getSearchAnalyzer(currentMapper));
|
setAnalyzer(parseContext.getSearchAnalyzer(currentMapper));
|
||||||
}
|
}
|
||||||
indexedNameField = currentMapper.names().indexName();
|
indexedNameField = currentMapper.fieldType().names().indexName();
|
||||||
return getPossiblyAnalyzedWildcardQuery(indexedNameField, termStr);
|
return getPossiblyAnalyzedWildcardQuery(indexedNameField, termStr);
|
||||||
}
|
}
|
||||||
return getPossiblyAnalyzedWildcardQuery(indexedNameField, termStr);
|
return getPossiblyAnalyzedWildcardQuery(indexedNameField, termStr);
|
||||||
|
|
|
@ -113,8 +113,8 @@ public class TransportAnalyzeAction extends TransportSingleCustomOperationAction
|
||||||
if (fieldMapper.isNumeric()) {
|
if (fieldMapper.isNumeric()) {
|
||||||
throw new IllegalArgumentException("Can't process field [" + request.field() + "], Analysis requests are not supported on numeric fields");
|
throw new IllegalArgumentException("Can't process field [" + request.field() + "], Analysis requests are not supported on numeric fields");
|
||||||
}
|
}
|
||||||
analyzer = fieldMapper.indexAnalyzer();
|
analyzer = fieldMapper.fieldType().indexAnalyzer();
|
||||||
field = fieldMapper.names().indexName();
|
field = fieldMapper.fieldType().names().indexName();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,7 +179,7 @@ public class TransportGetFieldMappingsIndexAction extends TransportSingleCustomO
|
||||||
for (String field : request.fields()) {
|
for (String field : request.fields()) {
|
||||||
if (Regex.isMatchAllPattern(field)) {
|
if (Regex.isMatchAllPattern(field)) {
|
||||||
for (FieldMapper fieldMapper : allFieldMappers) {
|
for (FieldMapper fieldMapper : allFieldMappers) {
|
||||||
addFieldMapper(fieldMapper.names().fullName(), fieldMapper, fieldMappings, request.includeDefaults());
|
addFieldMapper(fieldMapper.fieldType().names().fullName(), fieldMapper, fieldMappings, request.includeDefaults());
|
||||||
}
|
}
|
||||||
} else if (Regex.isSimpleMatchPattern(field)) {
|
} else if (Regex.isSimpleMatchPattern(field)) {
|
||||||
// go through the field mappers 3 times, to make sure we give preference to the resolve order: full name, index name, name.
|
// go through the field mappers 3 times, to make sure we give preference to the resolve order: full name, index name, name.
|
||||||
|
@ -187,22 +187,22 @@ public class TransportGetFieldMappingsIndexAction extends TransportSingleCustomO
|
||||||
Collection<FieldMapper> remainingFieldMappers = Lists.newLinkedList(allFieldMappers);
|
Collection<FieldMapper> remainingFieldMappers = Lists.newLinkedList(allFieldMappers);
|
||||||
for (Iterator<FieldMapper> it = remainingFieldMappers.iterator(); it.hasNext(); ) {
|
for (Iterator<FieldMapper> it = remainingFieldMappers.iterator(); it.hasNext(); ) {
|
||||||
final FieldMapper fieldMapper = it.next();
|
final FieldMapper fieldMapper = it.next();
|
||||||
if (Regex.simpleMatch(field, fieldMapper.names().fullName())) {
|
if (Regex.simpleMatch(field, fieldMapper.fieldType().names().fullName())) {
|
||||||
addFieldMapper(fieldMapper.names().fullName(), fieldMapper, fieldMappings, request.includeDefaults());
|
addFieldMapper(fieldMapper.fieldType().names().fullName(), fieldMapper, fieldMappings, request.includeDefaults());
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Iterator<FieldMapper> it = remainingFieldMappers.iterator(); it.hasNext(); ) {
|
for (Iterator<FieldMapper> it = remainingFieldMappers.iterator(); it.hasNext(); ) {
|
||||||
final FieldMapper fieldMapper = it.next();
|
final FieldMapper fieldMapper = it.next();
|
||||||
if (Regex.simpleMatch(field, fieldMapper.names().indexName())) {
|
if (Regex.simpleMatch(field, fieldMapper.fieldType().names().indexName())) {
|
||||||
addFieldMapper(fieldMapper.names().indexName(), fieldMapper, fieldMappings, request.includeDefaults());
|
addFieldMapper(fieldMapper.fieldType().names().indexName(), fieldMapper, fieldMappings, request.includeDefaults());
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Iterator<FieldMapper> it = remainingFieldMappers.iterator(); it.hasNext(); ) {
|
for (Iterator<FieldMapper> it = remainingFieldMappers.iterator(); it.hasNext(); ) {
|
||||||
final FieldMapper fieldMapper = it.next();
|
final FieldMapper fieldMapper = it.next();
|
||||||
if (Regex.simpleMatch(field, fieldMapper.names().shortName())) {
|
if (Regex.simpleMatch(field, fieldMapper.fieldType().names().shortName())) {
|
||||||
addFieldMapper(fieldMapper.names().shortName(), fieldMapper, fieldMappings, request.includeDefaults());
|
addFieldMapper(fieldMapper.fieldType().names().shortName(), fieldMapper, fieldMappings, request.includeDefaults());
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,7 @@ public class TransportGetFieldMappingsIndexAction extends TransportSingleCustomO
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
fieldMapper.toXContent(builder, includeDefaults ? includeDefaultsParams : ToXContent.EMPTY_PARAMS);
|
fieldMapper.toXContent(builder, includeDefaults ? includeDefaultsParams : ToXContent.EMPTY_PARAMS);
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
fieldMappings.put(field, new FieldMappingMetaData(fieldMapper.names().fullName(), builder.bytes()));
|
fieldMappings.put(field, new FieldMappingMetaData(fieldMapper.fieldType().names().fullName(), builder.bytes()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ElasticsearchException("failed to serialize XContent of field [" + field + "]", e);
|
throw new ElasticsearchException("failed to serialize XContent of field [" + field + "]", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,7 +289,7 @@ public class MappingMetaData extends AbstractDiffable<MappingMetaData> {
|
||||||
this.id = new Id(docMapper.idFieldMapper().path());
|
this.id = new Id(docMapper.idFieldMapper().path());
|
||||||
this.routing = new Routing(docMapper.routingFieldMapper().required(), docMapper.routingFieldMapper().path());
|
this.routing = new Routing(docMapper.routingFieldMapper().required(), docMapper.routingFieldMapper().path());
|
||||||
this.timestamp = new Timestamp(docMapper.timestampFieldMapper().enabled(), docMapper.timestampFieldMapper().path(),
|
this.timestamp = new Timestamp(docMapper.timestampFieldMapper().enabled(), docMapper.timestampFieldMapper().path(),
|
||||||
docMapper.timestampFieldMapper().dateTimeFormatter().format(), docMapper.timestampFieldMapper().defaultTimestamp(),
|
docMapper.timestampFieldMapper().fieldType().dateTimeFormatter().format(), docMapper.timestampFieldMapper().defaultTimestamp(),
|
||||||
docMapper.timestampFieldMapper().ignoreMissing());
|
docMapper.timestampFieldMapper().ignoreMissing());
|
||||||
this.hasParentField = docMapper.parentFieldMapper().active();
|
this.hasParentField = docMapper.parentFieldMapper().active();
|
||||||
}
|
}
|
||||||
|
|
|
@ -728,7 +728,7 @@ public abstract class ShapeBuilder implements ToXContent {
|
||||||
Distance radius = null;
|
Distance radius = null;
|
||||||
CoordinateNode node = null;
|
CoordinateNode node = null;
|
||||||
GeometryCollectionBuilder geometryCollections = null;
|
GeometryCollectionBuilder geometryCollections = null;
|
||||||
Orientation requestedOrientation = (shapeMapper == null) ? Orientation.RIGHT : shapeMapper.orientation();
|
Orientation requestedOrientation = (shapeMapper == null) ? Orientation.RIGHT : shapeMapper.fieldType().orientation();
|
||||||
|
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
package org.elasticsearch.index.fielddata;
|
package org.elasticsearch.index.fielddata;
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper.Loading;
|
import org.elasticsearch.index.mapper.MappedFieldType.Loading;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.IndexComponent;
|
import org.elasticsearch.index.IndexComponent;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||||
|
@ -77,7 +78,7 @@ public interface IndexFieldData<FD extends AtomicFieldData> extends IndexCompone
|
||||||
/**
|
/**
|
||||||
* The field name.
|
* The field name.
|
||||||
*/
|
*/
|
||||||
FieldMapper.Names getFieldNames();
|
MappedFieldType.Names getFieldNames();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The field data type.
|
* The field data type.
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.lucene.index.LeafReaderContext;
|
||||||
import org.apache.lucene.index.IndexReader;
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.util.Accountable;
|
import org.apache.lucene.util.Accountable;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple field data cache abstraction on the *index* level.
|
* A simple field data cache abstraction on the *index* level.
|
||||||
|
@ -47,9 +48,9 @@ public interface IndexFieldDataCache {
|
||||||
|
|
||||||
interface Listener {
|
interface Listener {
|
||||||
|
|
||||||
void onLoad(FieldMapper.Names fieldNames, FieldDataType fieldDataType, Accountable ramUsage);
|
void onLoad(MappedFieldType.Names fieldNames, FieldDataType fieldDataType, Accountable ramUsage);
|
||||||
|
|
||||||
void onUnload(FieldMapper.Names fieldNames, FieldDataType fieldDataType, boolean wasEvicted, long sizeInBytes);
|
void onUnload(MappedFieldType.Names fieldNames, FieldDataType fieldDataType, boolean wasEvicted, long sizeInBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
class None implements IndexFieldDataCache {
|
class None implements IndexFieldDataCache {
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.elasticsearch.index.AbstractIndexComponent;
|
||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.fielddata.plain.*;
|
import org.elasticsearch.index.fielddata.plain.*;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.core.BooleanFieldMapper;
|
import org.elasticsearch.index.mapper.core.BooleanFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.internal.IndexFieldMapper;
|
import org.elasticsearch.index.mapper.internal.IndexFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
||||||
|
@ -46,6 +47,8 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
import static org.elasticsearch.index.mapper.MappedFieldType.Names;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class IndexFieldDataService extends AbstractIndexComponent {
|
public class IndexFieldDataService extends AbstractIndexComponent {
|
||||||
|
@ -226,12 +229,12 @@ public class IndexFieldDataService extends AbstractIndexComponent {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <IFD extends IndexFieldData<?>> IFD getForField(FieldMapper mapper) {
|
public <IFD extends IndexFieldData<?>> IFD getForField(FieldMapper mapper) {
|
||||||
final FieldMapper.Names fieldNames = mapper.names();
|
final Names fieldNames = mapper.fieldType().names();
|
||||||
final FieldDataType type = mapper.fieldDataType();
|
final FieldDataType type = mapper.fieldType().fieldDataType();
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
throw new IllegalArgumentException("found no fielddata type for field [" + fieldNames.fullName() + "]");
|
throw new IllegalArgumentException("found no fielddata type for field [" + fieldNames.fullName() + "]");
|
||||||
}
|
}
|
||||||
final boolean docValues = mapper.hasDocValues();
|
final boolean docValues = mapper.fieldType().hasDocValues();
|
||||||
final String key = fieldNames.indexName();
|
final String key = fieldNames.indexName();
|
||||||
IndexFieldData<?> fieldData = loadedFieldData.get(key);
|
IndexFieldData<?> fieldData = loadedFieldData.get(key);
|
||||||
if (fieldData == null) {
|
if (fieldData == null) {
|
||||||
|
|
|
@ -26,7 +26,7 @@ import org.elasticsearch.common.metrics.CounterMetric;
|
||||||
import org.elasticsearch.common.regex.Regex;
|
import org.elasticsearch.common.regex.Regex;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
|
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import org.elasticsearch.index.shard.AbstractIndexShardComponent;
|
import org.elasticsearch.index.shard.AbstractIndexShardComponent;
|
||||||
import org.elasticsearch.index.shard.ShardId;
|
import org.elasticsearch.index.shard.ShardId;
|
||||||
|
@ -62,7 +62,7 @@ public class ShardFieldData extends AbstractIndexShardComponent implements Index
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad(FieldMapper.Names fieldNames, FieldDataType fieldDataType, Accountable ramUsage) {
|
public void onLoad(MappedFieldType.Names fieldNames, FieldDataType fieldDataType, Accountable ramUsage) {
|
||||||
totalMetric.inc(ramUsage.ramBytesUsed());
|
totalMetric.inc(ramUsage.ramBytesUsed());
|
||||||
String keyFieldName = fieldNames.indexName();
|
String keyFieldName = fieldNames.indexName();
|
||||||
CounterMetric total = perFieldTotals.get(keyFieldName);
|
CounterMetric total = perFieldTotals.get(keyFieldName);
|
||||||
|
@ -79,7 +79,7 @@ public class ShardFieldData extends AbstractIndexShardComponent implements Index
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUnload(FieldMapper.Names fieldNames, FieldDataType fieldDataType, boolean wasEvicted, long sizeInBytes) {
|
public void onUnload(MappedFieldType.Names fieldNames, FieldDataType fieldDataType, boolean wasEvicted, long sizeInBytes) {
|
||||||
if (wasEvicted) {
|
if (wasEvicted) {
|
||||||
evictionsMetric.inc();
|
evictionsMetric.inc();
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||||
import org.elasticsearch.index.fielddata.IndexOrdinalsFieldData;
|
import org.elasticsearch.index.fielddata.IndexOrdinalsFieldData;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.search.MultiValueMode;
|
import org.elasticsearch.search.MultiValueMode;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -41,11 +42,11 @@ import java.util.Collections;
|
||||||
*/
|
*/
|
||||||
public abstract class GlobalOrdinalsIndexFieldData extends AbstractIndexComponent implements IndexOrdinalsFieldData, Accountable {
|
public abstract class GlobalOrdinalsIndexFieldData extends AbstractIndexComponent implements IndexOrdinalsFieldData, Accountable {
|
||||||
|
|
||||||
private final FieldMapper.Names fieldNames;
|
private final MappedFieldType.Names fieldNames;
|
||||||
private final FieldDataType fieldDataType;
|
private final FieldDataType fieldDataType;
|
||||||
private final long memorySizeInBytes;
|
private final long memorySizeInBytes;
|
||||||
|
|
||||||
protected GlobalOrdinalsIndexFieldData(Index index, Settings settings, FieldMapper.Names fieldNames, FieldDataType fieldDataType, long memorySizeInBytes) {
|
protected GlobalOrdinalsIndexFieldData(Index index, Settings settings, MappedFieldType.Names fieldNames, FieldDataType fieldDataType, long memorySizeInBytes) {
|
||||||
super(index, settings);
|
super(index, settings);
|
||||||
this.fieldNames = fieldNames;
|
this.fieldNames = fieldNames;
|
||||||
this.fieldDataType = fieldDataType;
|
this.fieldDataType = fieldDataType;
|
||||||
|
@ -68,7 +69,7 @@ public abstract class GlobalOrdinalsIndexFieldData extends AbstractIndexComponen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldMapper.Names getFieldNames() {
|
public MappedFieldType.Names getFieldNames() {
|
||||||
return fieldNames;
|
return fieldNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.elasticsearch.index.fielddata.AtomicOrdinalsFieldData;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
import org.elasticsearch.index.fielddata.plain.AbstractAtomicOrdinalsFieldData;
|
import org.elasticsearch.index.fielddata.plain.AbstractAtomicOrdinalsFieldData;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ final class InternalGlobalOrdinalsIndexFieldData extends GlobalOrdinalsIndexFiel
|
||||||
|
|
||||||
private final Atomic[] atomicReaders;
|
private final Atomic[] atomicReaders;
|
||||||
|
|
||||||
InternalGlobalOrdinalsIndexFieldData(Index index, Settings settings, FieldMapper.Names fieldNames, FieldDataType fieldDataType, AtomicOrdinalsFieldData[] segmentAfd, OrdinalMap ordinalMap, long memorySizeInBytes) {
|
InternalGlobalOrdinalsIndexFieldData(Index index, Settings settings, MappedFieldType.Names fieldNames, FieldDataType fieldDataType, AtomicOrdinalsFieldData[] segmentAfd, OrdinalMap ordinalMap, long memorySizeInBytes) {
|
||||||
super(index, settings, fieldNames, fieldDataType, memorySizeInBytes);
|
super(index, settings, fieldNames, fieldDataType, memorySizeInBytes);
|
||||||
this.atomicReaders = new Atomic[segmentAfd.length];
|
this.atomicReaders = new Atomic[segmentAfd.length];
|
||||||
for (int i = 0; i < segmentAfd.length; i++) {
|
for (int i = 0; i < segmentAfd.length; i++) {
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.elasticsearch.index.AbstractIndexComponent;
|
||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.fielddata.*;
|
import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -38,11 +39,11 @@ import java.io.IOException;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractIndexFieldData<FD extends AtomicFieldData> extends AbstractIndexComponent implements IndexFieldData<FD> {
|
public abstract class AbstractIndexFieldData<FD extends AtomicFieldData> extends AbstractIndexComponent implements IndexFieldData<FD> {
|
||||||
|
|
||||||
private final FieldMapper.Names fieldNames;
|
private final MappedFieldType.Names fieldNames;
|
||||||
protected final FieldDataType fieldDataType;
|
protected final FieldDataType fieldDataType;
|
||||||
protected final IndexFieldDataCache cache;
|
protected final IndexFieldDataCache cache;
|
||||||
|
|
||||||
public AbstractIndexFieldData(Index index, @IndexSettings Settings indexSettings, FieldMapper.Names fieldNames, FieldDataType fieldDataType, IndexFieldDataCache cache) {
|
public AbstractIndexFieldData(Index index, @IndexSettings Settings indexSettings, MappedFieldType.Names fieldNames, FieldDataType fieldDataType, IndexFieldDataCache cache) {
|
||||||
super(index, indexSettings);
|
super(index, indexSettings);
|
||||||
this.fieldNames = fieldNames;
|
this.fieldNames = fieldNames;
|
||||||
this.fieldDataType = fieldDataType;
|
this.fieldDataType = fieldDataType;
|
||||||
|
@ -50,7 +51,7 @@ public abstract class AbstractIndexFieldData<FD extends AtomicFieldData> extends
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldMapper.Names getFieldNames() {
|
public MappedFieldType.Names getFieldNames() {
|
||||||
return this.fieldNames;
|
return this.fieldNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.index.Index;
|
import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.fielddata.*;
|
import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper.Names;
|
import org.elasticsearch.index.mapper.MappedFieldType.Names;
|
||||||
import org.elasticsearch.search.MultiValueMode;
|
import org.elasticsearch.search.MultiValueMode;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
|
@ -29,7 +29,7 @@ import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.GlobalOrdinalsBuilder;
|
import org.elasticsearch.index.fielddata.ordinals.GlobalOrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper.Names;
|
import org.elasticsearch.index.mapper.MappedFieldType.Names;
|
||||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||||
import org.elasticsearch.search.MultiValueMode;
|
import org.elasticsearch.search.MultiValueMode;
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper.Names;
|
import org.elasticsearch.index.mapper.MappedFieldType.Names;
|
||||||
import org.elasticsearch.search.MultiValueMode;
|
import org.elasticsearch.search.MultiValueMode;
|
||||||
|
|
||||||
public class BinaryDVIndexFieldData extends DocValuesIndexFieldData implements IndexFieldData<BinaryDVAtomicFieldData> {
|
public class BinaryDVIndexFieldData extends DocValuesIndexFieldData implements IndexFieldData<BinaryDVAtomicFieldData> {
|
||||||
|
|
|
@ -39,7 +39,7 @@ import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.FloatValuesComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.FloatValuesComparatorSource;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.LongValuesComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.LongValuesComparatorSource;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper.Names;
|
import org.elasticsearch.index.mapper.MappedFieldType.Names;
|
||||||
import org.elasticsearch.search.MultiValueMode;
|
import org.elasticsearch.search.MultiValueMode;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
|
@ -29,7 +29,7 @@ import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper.Names;
|
import org.elasticsearch.index.mapper.MappedFieldType.Names;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||||
import org.elasticsearch.search.MultiValueMode;
|
import org.elasticsearch.search.MultiValueMode;
|
||||||
|
@ -67,8 +67,8 @@ public class BytesBinaryDVIndexFieldData extends DocValuesIndexFieldData impleme
|
||||||
public IndexFieldData<?> build(Index index, Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
public IndexFieldData<?> build(Index index, Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
||||||
CircuitBreakerService breakerService, MapperService mapperService) {
|
CircuitBreakerService breakerService, MapperService mapperService) {
|
||||||
// Ignore breaker
|
// Ignore breaker
|
||||||
final Names fieldNames = mapper.names();
|
final Names fieldNames = mapper.fieldType().names();
|
||||||
return new BytesBinaryDVIndexFieldData(index, fieldNames, mapper.fieldDataType());
|
return new BytesBinaryDVIndexFieldData(index, fieldNames, mapper.fieldType().fieldDataType());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.fielddata.*;
|
import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper.Names;
|
import org.elasticsearch.index.mapper.MappedFieldType.Names;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import org.elasticsearch.search.MultiValueMode;
|
import org.elasticsearch.search.MultiValueMode;
|
||||||
|
@ -42,7 +42,7 @@ public final class DisabledIndexFieldData extends AbstractIndexFieldData<AtomicF
|
||||||
public IndexFieldData<AtomicFieldData> build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper,
|
public IndexFieldData<AtomicFieldData> build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper,
|
||||||
IndexFieldDataCache cache, CircuitBreakerService breakerService, MapperService mapperService) {
|
IndexFieldDataCache cache, CircuitBreakerService breakerService, MapperService mapperService) {
|
||||||
// Ignore Circuit Breaker
|
// Ignore Circuit Breaker
|
||||||
return new DisabledIndexFieldData(index, indexSettings, mapper.names(), mapper.fieldDataType(), cache);
|
return new DisabledIndexFieldData(index, indexSettings, mapper.fieldType().names(), mapper.fieldType().fieldDataType(), cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,8 @@ import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
||||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData.NumericType;
|
import org.elasticsearch.index.fielddata.IndexNumericFieldData.NumericType;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper.Names;
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType.Names;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.mapper.internal.IdFieldMapper;
|
import org.elasticsearch.index.mapper.internal.IdFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.internal.TimestampFieldMapper;
|
import org.elasticsearch.index.mapper.internal.TimestampFieldMapper;
|
||||||
|
@ -93,8 +94,8 @@ public abstract class DocValuesIndexFieldData {
|
||||||
public IndexFieldData<?> build(Index index, Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
public IndexFieldData<?> build(Index index, Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
||||||
CircuitBreakerService breakerService, MapperService mapperService) {
|
CircuitBreakerService breakerService, MapperService mapperService) {
|
||||||
// Ignore Circuit Breaker
|
// Ignore Circuit Breaker
|
||||||
final FieldMapper.Names fieldNames = mapper.names();
|
final Names fieldNames = mapper.fieldType().names();
|
||||||
final Settings fdSettings = mapper.fieldDataType().getSettings();
|
final Settings fdSettings = mapper.fieldType().fieldDataType().getSettings();
|
||||||
final Map<String, Settings> filter = fdSettings.getGroups("filter");
|
final Map<String, Settings> filter = fdSettings.getGroups("filter");
|
||||||
if (filter != null && !filter.isEmpty()) {
|
if (filter != null && !filter.isEmpty()) {
|
||||||
throw new IllegalArgumentException("Doc values field data doesn't support filters [" + fieldNames.fullName() + "]");
|
throw new IllegalArgumentException("Doc values field data doesn't support filters [" + fieldNames.fullName() + "]");
|
||||||
|
@ -102,19 +103,19 @@ public abstract class DocValuesIndexFieldData {
|
||||||
|
|
||||||
if (BINARY_INDEX_FIELD_NAMES.contains(fieldNames.indexName())) {
|
if (BINARY_INDEX_FIELD_NAMES.contains(fieldNames.indexName())) {
|
||||||
assert numericType == null;
|
assert numericType == null;
|
||||||
return new BinaryDVIndexFieldData(index, fieldNames, mapper.fieldDataType());
|
return new BinaryDVIndexFieldData(index, fieldNames, mapper.fieldType().fieldDataType());
|
||||||
} else if (NUMERIC_INDEX_FIELD_NAMES.contains(fieldNames.indexName())) {
|
} else if (NUMERIC_INDEX_FIELD_NAMES.contains(fieldNames.indexName())) {
|
||||||
assert !numericType.isFloatingPoint();
|
assert !numericType.isFloatingPoint();
|
||||||
return new NumericDVIndexFieldData(index, fieldNames, mapper.fieldDataType());
|
return new NumericDVIndexFieldData(index, fieldNames, mapper.fieldType().fieldDataType());
|
||||||
} else if (numericType != null) {
|
} else if (numericType != null) {
|
||||||
if (Version.indexCreated(indexSettings).onOrAfter(Version.V_1_4_0_Beta1)) {
|
if (Version.indexCreated(indexSettings).onOrAfter(Version.V_1_4_0_Beta1)) {
|
||||||
return new SortedNumericDVIndexFieldData(index, fieldNames, numericType, mapper.fieldDataType());
|
return new SortedNumericDVIndexFieldData(index, fieldNames, numericType, mapper.fieldType().fieldDataType());
|
||||||
} else {
|
} else {
|
||||||
// prior to ES 1.4: multi-valued numerics were boxed inside a byte[] as BINARY
|
// prior to ES 1.4: multi-valued numerics were boxed inside a byte[] as BINARY
|
||||||
return new BinaryDVNumericIndexFieldData(index, fieldNames, numericType, mapper.fieldDataType());
|
return new BinaryDVNumericIndexFieldData(index, fieldNames, numericType, mapper.fieldType().fieldDataType());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return new SortedSetDVOrdinalsIndexFieldData(index, cache, indexSettings, fieldNames, breakerService, mapper.fieldDataType());
|
return new SortedSetDVOrdinalsIndexFieldData(index, cache, indexSettings, fieldNames, breakerService, mapper.fieldType().fieldDataType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ import org.elasticsearch.index.fielddata.fieldcomparator.DoubleValuesComparatorS
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||||
|
@ -74,11 +75,11 @@ public class DoubleArrayIndexFieldData extends AbstractIndexFieldData<AtomicNume
|
||||||
@Override
|
@Override
|
||||||
public IndexFieldData<?> build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
public IndexFieldData<?> build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
||||||
CircuitBreakerService breakerService, MapperService mapperService) {
|
CircuitBreakerService breakerService, MapperService mapperService) {
|
||||||
return new DoubleArrayIndexFieldData(index, indexSettings, mapper.names(), mapper.fieldDataType(), cache, breakerService);
|
return new DoubleArrayIndexFieldData(index, indexSettings, mapper.fieldType().names(), mapper.fieldType().fieldDataType(), cache, breakerService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DoubleArrayIndexFieldData(Index index, @IndexSettings Settings indexSettings, FieldMapper.Names fieldNames,
|
public DoubleArrayIndexFieldData(Index index, @IndexSettings Settings indexSettings, MappedFieldType.Names fieldNames,
|
||||||
FieldDataType fieldDataType, IndexFieldDataCache cache, CircuitBreakerService breakerService) {
|
FieldDataType fieldDataType, IndexFieldDataCache cache, CircuitBreakerService breakerService) {
|
||||||
super(index, indexSettings, fieldNames, fieldDataType, cache);
|
super(index, indexSettings, fieldNames, fieldDataType, cache);
|
||||||
this.breakerService = breakerService;
|
this.breakerService = breakerService;
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||||
|
@ -48,11 +49,11 @@ public class FSTBytesIndexFieldData extends AbstractIndexOrdinalsFieldData {
|
||||||
@Override
|
@Override
|
||||||
public IndexOrdinalsFieldData build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper,
|
public IndexOrdinalsFieldData build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper,
|
||||||
IndexFieldDataCache cache, CircuitBreakerService breakerService, MapperService mapperService) {
|
IndexFieldDataCache cache, CircuitBreakerService breakerService, MapperService mapperService) {
|
||||||
return new FSTBytesIndexFieldData(index, indexSettings, mapper.names(), mapper.fieldDataType(), cache, breakerService);
|
return new FSTBytesIndexFieldData(index, indexSettings, mapper.fieldType().names(), mapper.fieldType().fieldDataType(), cache, breakerService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FSTBytesIndexFieldData(Index index, @IndexSettings Settings indexSettings, FieldMapper.Names fieldNames, FieldDataType fieldDataType,
|
FSTBytesIndexFieldData(Index index, @IndexSettings Settings indexSettings, MappedFieldType.Names fieldNames, FieldDataType fieldDataType,
|
||||||
IndexFieldDataCache cache, CircuitBreakerService breakerService) {
|
IndexFieldDataCache cache, CircuitBreakerService breakerService) {
|
||||||
super(index, indexSettings, fieldNames, fieldDataType, cache, breakerService);
|
super(index, indexSettings, fieldNames, fieldDataType, cache, breakerService);
|
||||||
this.breakerService = breakerService;
|
this.breakerService = breakerService;
|
||||||
|
|
|
@ -52,6 +52,7 @@ import org.elasticsearch.index.fielddata.fieldcomparator.FloatValuesComparatorSo
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||||
|
@ -73,11 +74,11 @@ public class FloatArrayIndexFieldData extends AbstractIndexFieldData<AtomicNumer
|
||||||
@Override
|
@Override
|
||||||
public IndexFieldData<?> build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
public IndexFieldData<?> build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
||||||
CircuitBreakerService breakerService, MapperService mapperService) {
|
CircuitBreakerService breakerService, MapperService mapperService) {
|
||||||
return new FloatArrayIndexFieldData(index, indexSettings, mapper.names(), mapper.fieldDataType(), cache, breakerService);
|
return new FloatArrayIndexFieldData(index, indexSettings, mapper.fieldType().names(), mapper.fieldType().fieldDataType(), cache, breakerService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public FloatArrayIndexFieldData(Index index, @IndexSettings Settings indexSettings, FieldMapper.Names fieldNames,
|
public FloatArrayIndexFieldData(Index index, @IndexSettings Settings indexSettings, MappedFieldType.Names fieldNames,
|
||||||
FieldDataType fieldDataType, IndexFieldDataCache cache, CircuitBreakerService breakerService) {
|
FieldDataType fieldDataType, IndexFieldDataCache cache, CircuitBreakerService breakerService) {
|
||||||
super(index, indexSettings, fieldNames, fieldDataType, cache);
|
super(index, indexSettings, fieldNames, fieldDataType, cache);
|
||||||
this.breakerService = breakerService;
|
this.breakerService = breakerService;
|
||||||
|
|
|
@ -27,7 +27,8 @@ import org.elasticsearch.index.Index;
|
||||||
import org.elasticsearch.index.fielddata.*;
|
import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper.Names;
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType.Names;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||||
import org.elasticsearch.search.MultiValueMode;
|
import org.elasticsearch.search.MultiValueMode;
|
||||||
|
@ -65,8 +66,8 @@ public class GeoPointBinaryDVIndexFieldData extends DocValuesIndexFieldData impl
|
||||||
public IndexFieldData<?> build(Index index, Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
public IndexFieldData<?> build(Index index, Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
||||||
CircuitBreakerService breakerService, MapperService mapperService) {
|
CircuitBreakerService breakerService, MapperService mapperService) {
|
||||||
// Ignore breaker
|
// Ignore breaker
|
||||||
final FieldMapper.Names fieldNames = mapper.names();
|
final Names fieldNames = mapper.fieldType().names();
|
||||||
return new GeoPointBinaryDVIndexFieldData(index, fieldNames, mapper.fieldDataType());
|
return new GeoPointBinaryDVIndexFieldData(index, fieldNames, mapper.fieldType().fieldDataType());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
|
@ -54,7 +55,7 @@ public class GeoPointCompressedIndexFieldData extends AbstractIndexGeoPointField
|
||||||
@Override
|
@Override
|
||||||
public IndexFieldData<?> build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
public IndexFieldData<?> build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
||||||
CircuitBreakerService breakerService, MapperService mapperService) {
|
CircuitBreakerService breakerService, MapperService mapperService) {
|
||||||
FieldDataType type = mapper.fieldDataType();
|
FieldDataType type = mapper.fieldType().fieldDataType();
|
||||||
final String precisionAsString = type.getSettings().get(PRECISION_KEY);
|
final String precisionAsString = type.getSettings().get(PRECISION_KEY);
|
||||||
final Distance precision;
|
final Distance precision;
|
||||||
if (precisionAsString != null) {
|
if (precisionAsString != null) {
|
||||||
|
@ -62,13 +63,13 @@ public class GeoPointCompressedIndexFieldData extends AbstractIndexGeoPointField
|
||||||
} else {
|
} else {
|
||||||
precision = DEFAULT_PRECISION_VALUE;
|
precision = DEFAULT_PRECISION_VALUE;
|
||||||
}
|
}
|
||||||
return new GeoPointCompressedIndexFieldData(index, indexSettings, mapper.names(), mapper.fieldDataType(), cache, precision, breakerService);
|
return new GeoPointCompressedIndexFieldData(index, indexSettings, mapper.fieldType().names(), mapper.fieldType().fieldDataType(), cache, precision, breakerService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final GeoPointFieldMapper.Encoding encoding;
|
private final GeoPointFieldMapper.Encoding encoding;
|
||||||
|
|
||||||
public GeoPointCompressedIndexFieldData(Index index, @IndexSettings Settings indexSettings, FieldMapper.Names fieldNames,
|
public GeoPointCompressedIndexFieldData(Index index, @IndexSettings Settings indexSettings, MappedFieldType.Names fieldNames,
|
||||||
FieldDataType fieldDataType, IndexFieldDataCache cache, Distance precision,
|
FieldDataType fieldDataType, IndexFieldDataCache cache, Distance precision,
|
||||||
CircuitBreakerService breakerService) {
|
CircuitBreakerService breakerService) {
|
||||||
super(index, indexSettings, fieldNames, fieldDataType, cache);
|
super(index, indexSettings, fieldNames, fieldDataType, cache);
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||||
|
@ -48,11 +49,11 @@ public class GeoPointDoubleArrayIndexFieldData extends AbstractIndexGeoPointFiel
|
||||||
@Override
|
@Override
|
||||||
public IndexFieldData<?> build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
public IndexFieldData<?> build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
||||||
CircuitBreakerService breakerService, MapperService mapperService) {
|
CircuitBreakerService breakerService, MapperService mapperService) {
|
||||||
return new GeoPointDoubleArrayIndexFieldData(index, indexSettings, mapper.names(), mapper.fieldDataType(), cache, breakerService);
|
return new GeoPointDoubleArrayIndexFieldData(index, indexSettings, mapper.fieldType().names(), mapper.fieldType().fieldDataType(), cache, breakerService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeoPointDoubleArrayIndexFieldData(Index index, @IndexSettings Settings indexSettings, FieldMapper.Names fieldNames,
|
public GeoPointDoubleArrayIndexFieldData(Index index, @IndexSettings Settings indexSettings, MappedFieldType.Names fieldNames,
|
||||||
FieldDataType fieldDataType, IndexFieldDataCache cache, CircuitBreakerService breakerService) {
|
FieldDataType fieldDataType, IndexFieldDataCache cache, CircuitBreakerService breakerService) {
|
||||||
super(index, indexSettings, fieldNames, fieldDataType, cache);
|
super(index, indexSettings, fieldNames, fieldDataType, cache);
|
||||||
this.breakerService = breakerService;
|
this.breakerService = breakerService;
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
||||||
import org.elasticsearch.index.fielddata.IndexOrdinalsFieldData;
|
import org.elasticsearch.index.fielddata.IndexOrdinalsFieldData;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||||
|
|
||||||
|
@ -47,7 +48,7 @@ public class IndexIndexFieldData extends AbstractIndexOrdinalsFieldData {
|
||||||
@Override
|
@Override
|
||||||
public IndexFieldData<?> build(Index index, Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
public IndexFieldData<?> build(Index index, Settings indexSettings, FieldMapper mapper, IndexFieldDataCache cache,
|
||||||
CircuitBreakerService breakerService, MapperService mapperService) {
|
CircuitBreakerService breakerService, MapperService mapperService) {
|
||||||
return new IndexIndexFieldData(index, mapper.names());
|
return new IndexIndexFieldData(index, mapper.fieldType().names());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -101,7 +102,7 @@ public class IndexIndexFieldData extends AbstractIndexOrdinalsFieldData {
|
||||||
|
|
||||||
private final AtomicOrdinalsFieldData atomicFieldData;
|
private final AtomicOrdinalsFieldData atomicFieldData;
|
||||||
|
|
||||||
private IndexIndexFieldData(Index index, FieldMapper.Names names) {
|
private IndexIndexFieldData(Index index, MappedFieldType.Names names) {
|
||||||
super(index, Settings.EMPTY, names, new FieldDataType("string"), null, null);
|
super(index, Settings.EMPTY, names, new FieldDataType("string"), null, null);
|
||||||
atomicFieldData = new IndexAtomicFieldData(index().name());
|
atomicFieldData = new IndexAtomicFieldData(index().name());
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.LongValuesComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.LongValuesComparatorSource;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper.Names;
|
import org.elasticsearch.index.mapper.MappedFieldType.Names;
|
||||||
import org.elasticsearch.search.MultiValueMode;
|
import org.elasticsearch.search.MultiValueMode;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
|
@ -57,6 +57,7 @@ import org.elasticsearch.index.fielddata.fieldcomparator.LongValuesComparatorSou
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||||
|
@ -86,14 +87,14 @@ public class PackedArrayIndexFieldData extends AbstractIndexFieldData<AtomicNume
|
||||||
@Override
|
@Override
|
||||||
public IndexFieldData<AtomicNumericFieldData> build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper,
|
public IndexFieldData<AtomicNumericFieldData> build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper,
|
||||||
IndexFieldDataCache cache, CircuitBreakerService breakerService, MapperService mapperService) {
|
IndexFieldDataCache cache, CircuitBreakerService breakerService, MapperService mapperService) {
|
||||||
return new PackedArrayIndexFieldData(index, indexSettings, mapper.names(), mapper.fieldDataType(), cache, numericType, breakerService);
|
return new PackedArrayIndexFieldData(index, indexSettings, mapper.fieldType().names(), mapper.fieldType().fieldDataType(), cache, numericType, breakerService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final NumericType numericType;
|
private final NumericType numericType;
|
||||||
private final CircuitBreakerService breakerService;
|
private final CircuitBreakerService breakerService;
|
||||||
|
|
||||||
public PackedArrayIndexFieldData(Index index, @IndexSettings Settings indexSettings, FieldMapper.Names fieldNames,
|
public PackedArrayIndexFieldData(Index index, @IndexSettings Settings indexSettings, MappedFieldType.Names fieldNames,
|
||||||
FieldDataType fieldDataType, IndexFieldDataCache cache, NumericType numericType,
|
FieldDataType fieldDataType, IndexFieldDataCache cache, NumericType numericType,
|
||||||
CircuitBreakerService breakerService) {
|
CircuitBreakerService breakerService) {
|
||||||
super(index, indexSettings, fieldNames, fieldDataType, cache);
|
super(index, indexSettings, fieldNames, fieldDataType, cache);
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
import org.elasticsearch.index.fielddata.ordinals.Ordinals;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.settings.IndexSettings;
|
import org.elasticsearch.index.settings.IndexSettings;
|
||||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||||
|
@ -49,11 +50,11 @@ public class PagedBytesIndexFieldData extends AbstractIndexOrdinalsFieldData {
|
||||||
@Override
|
@Override
|
||||||
public IndexOrdinalsFieldData build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper,
|
public IndexOrdinalsFieldData build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper,
|
||||||
IndexFieldDataCache cache, CircuitBreakerService breakerService, MapperService mapperService) {
|
IndexFieldDataCache cache, CircuitBreakerService breakerService, MapperService mapperService) {
|
||||||
return new PagedBytesIndexFieldData(index, indexSettings, mapper.names(), mapper.fieldDataType(), cache, breakerService);
|
return new PagedBytesIndexFieldData(index, indexSettings, mapper.fieldType().names(), mapper.fieldType().fieldDataType(), cache, breakerService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PagedBytesIndexFieldData(Index index, @IndexSettings Settings indexSettings, FieldMapper.Names fieldNames,
|
public PagedBytesIndexFieldData(Index index, @IndexSettings Settings indexSettings, MappedFieldType.Names fieldNames,
|
||||||
FieldDataType fieldDataType, IndexFieldDataCache cache, CircuitBreakerService breakerService) {
|
FieldDataType fieldDataType, IndexFieldDataCache cache, CircuitBreakerService breakerService) {
|
||||||
super(index, indexSettings, fieldNames, fieldDataType, cache, breakerService);
|
super(index, indexSettings, fieldNames, fieldDataType, cache, breakerService);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,8 @@ import org.elasticsearch.index.fielddata.ordinals.OrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||||
import org.elasticsearch.index.mapper.DocumentTypeListener;
|
import org.elasticsearch.index.mapper.DocumentTypeListener;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper.Names;
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType.Names;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.internal.UidFieldMapper;
|
import org.elasticsearch.index.mapper.internal.UidFieldMapper;
|
||||||
|
@ -96,7 +97,7 @@ public class ParentChildIndexFieldData extends AbstractIndexFieldData<AtomicPare
|
||||||
// while loading.
|
// while loading.
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
|
|
||||||
public ParentChildIndexFieldData(Index index, @IndexSettings Settings indexSettings, FieldMapper.Names fieldNames,
|
public ParentChildIndexFieldData(Index index, @IndexSettings Settings indexSettings, MappedFieldType.Names fieldNames,
|
||||||
FieldDataType fieldDataType, IndexFieldDataCache cache, MapperService mapperService,
|
FieldDataType fieldDataType, IndexFieldDataCache cache, MapperService mapperService,
|
||||||
CircuitBreakerService breakerService) {
|
CircuitBreakerService breakerService) {
|
||||||
super(index, indexSettings, fieldNames, fieldDataType, cache);
|
super(index, indexSettings, fieldNames, fieldDataType, cache);
|
||||||
|
@ -228,8 +229,8 @@ public class ParentChildIndexFieldData extends AbstractIndexFieldData<AtomicPare
|
||||||
public IndexFieldData<?> build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper,
|
public IndexFieldData<?> build(Index index, @IndexSettings Settings indexSettings, FieldMapper mapper,
|
||||||
IndexFieldDataCache cache, CircuitBreakerService breakerService,
|
IndexFieldDataCache cache, CircuitBreakerService breakerService,
|
||||||
MapperService mapperService) {
|
MapperService mapperService) {
|
||||||
return new ParentChildIndexFieldData(index, indexSettings, mapper.names(), mapper.fieldDataType(), cache,
|
return new ParentChildIndexFieldData(index, indexSettings, mapper.fieldType().names(), mapper.fieldType().fieldDataType(), cache,
|
||||||
mapperService, breakerService);
|
mapperService, breakerService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.FloatValuesComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.FloatValuesComparatorSource;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.LongValuesComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.LongValuesComparatorSource;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper.Names;
|
import org.elasticsearch.index.mapper.MappedFieldType.Names;
|
||||||
import org.elasticsearch.search.MultiValueMode;
|
import org.elasticsearch.search.MultiValueMode;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.elasticsearch.index.fielddata.*;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||||
import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource;
|
import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource;
|
||||||
import org.elasticsearch.index.fielddata.ordinals.GlobalOrdinalsBuilder;
|
import org.elasticsearch.index.fielddata.ordinals.GlobalOrdinalsBuilder;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper.Names;
|
import org.elasticsearch.index.mapper.MappedFieldType.Names;
|
||||||
import org.elasticsearch.search.MultiValueMode;
|
import org.elasticsearch.search.MultiValueMode;
|
||||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class SingleFieldsVisitor extends FieldsVisitor {
|
||||||
if (fieldsValues == null) {
|
if (fieldsValues == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<Object> fieldValues = fieldsValues.get(mapper.names().indexName());
|
List<Object> fieldValues = fieldsValues.get(mapper.fieldType().names().indexName());
|
||||||
if (fieldValues == null) {
|
if (fieldValues == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,19 +59,19 @@ public final class DocumentFieldMappers implements Iterable<FieldMapper> {
|
||||||
FieldNameAnalyzer indexAnalyzer = this.indexAnalyzer.copyAndAddAll(Collections2.transform(newMappers, new Function<FieldMapper, Map.Entry<String, Analyzer>>() {
|
FieldNameAnalyzer indexAnalyzer = this.indexAnalyzer.copyAndAddAll(Collections2.transform(newMappers, new Function<FieldMapper, Map.Entry<String, Analyzer>>() {
|
||||||
@Override
|
@Override
|
||||||
public Map.Entry<String, Analyzer> apply(FieldMapper input) {
|
public Map.Entry<String, Analyzer> apply(FieldMapper input) {
|
||||||
return Maps.immutableEntry(input.names().indexName(), input.indexAnalyzer());
|
return Maps.immutableEntry(input.fieldType().names().indexName(), (Analyzer)input.fieldType().indexAnalyzer());
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
FieldNameAnalyzer searchAnalyzer = this.searchAnalyzer.copyAndAddAll(Collections2.transform(newMappers, new Function<FieldMapper, Map.Entry<String, Analyzer>>() {
|
FieldNameAnalyzer searchAnalyzer = this.searchAnalyzer.copyAndAddAll(Collections2.transform(newMappers, new Function<FieldMapper, Map.Entry<String, Analyzer>>() {
|
||||||
@Override
|
@Override
|
||||||
public Map.Entry<String, Analyzer> apply(FieldMapper input) {
|
public Map.Entry<String, Analyzer> apply(FieldMapper input) {
|
||||||
return Maps.immutableEntry(input.names().indexName(), input.searchAnalyzer());
|
return Maps.immutableEntry(input.fieldType().names().indexName(), (Analyzer)input.fieldType().searchAnalyzer());
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
FieldNameAnalyzer searchQuoteAnalyzer = this.searchQuoteAnalyzer.copyAndAddAll(Collections2.transform(newMappers, new Function<FieldMapper, Map.Entry<String, Analyzer>>() {
|
FieldNameAnalyzer searchQuoteAnalyzer = this.searchQuoteAnalyzer.copyAndAddAll(Collections2.transform(newMappers, new Function<FieldMapper, Map.Entry<String, Analyzer>>() {
|
||||||
@Override
|
@Override
|
||||||
public Map.Entry<String, Analyzer> apply(FieldMapper input) {
|
public Map.Entry<String, Analyzer> apply(FieldMapper input) {
|
||||||
return Maps.immutableEntry(input.names().indexName(), input.searchQuoteAnalyzer());
|
return Maps.immutableEntry(input.fieldType().names().indexName(), (Analyzer)input.fieldType().searchQuoteAnalyzer());
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
return new DocumentFieldMappers(fieldMappers, indexAnalyzer, searchAnalyzer, searchQuoteAnalyzer);
|
return new DocumentFieldMappers(fieldMappers, indexAnalyzer, searchAnalyzer, searchQuoteAnalyzer);
|
||||||
|
|
|
@ -19,9 +19,6 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.mapper;
|
package org.elasticsearch.index.mapper;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
import org.apache.lucene.index.Terms;
|
import org.apache.lucene.index.Terms;
|
||||||
import org.apache.lucene.search.MultiTermQuery;
|
import org.apache.lucene.search.MultiTermQuery;
|
||||||
|
@ -30,10 +27,8 @@ import org.apache.lucene.util.BytesRef;
|
||||||
import org.elasticsearch.action.fieldstats.FieldStats;
|
import org.elasticsearch.action.fieldstats.FieldStats;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.unit.Fuzziness;
|
import org.elasticsearch.common.unit.Fuzziness;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
|
||||||
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -45,146 +40,7 @@ public interface FieldMapper extends Mapper {
|
||||||
|
|
||||||
String DOC_VALUES_FORMAT = "doc_values_format";
|
String DOC_VALUES_FORMAT = "doc_values_format";
|
||||||
|
|
||||||
class Names {
|
MappedFieldType fieldType();
|
||||||
|
|
||||||
private final String shortName;
|
|
||||||
|
|
||||||
private final String indexName;
|
|
||||||
|
|
||||||
private final String originalIndexName;
|
|
||||||
|
|
||||||
private final String fullName;
|
|
||||||
|
|
||||||
public Names(String name) {
|
|
||||||
this(name, name, name, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Names(String shortName, String indexName, String originalIndexName, String fullName) {
|
|
||||||
this.shortName = shortName;
|
|
||||||
this.indexName = indexName;
|
|
||||||
this.originalIndexName = originalIndexName;
|
|
||||||
this.fullName = fullName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The logical name of the field.
|
|
||||||
*/
|
|
||||||
public String shortName() {
|
|
||||||
return shortName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The indexed name of the field. This is the name under which we will
|
|
||||||
* store it in the index.
|
|
||||||
*/
|
|
||||||
public String indexName() {
|
|
||||||
return indexName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The original index name, before any "path" modifications performed on it.
|
|
||||||
*/
|
|
||||||
public String originalIndexName() {
|
|
||||||
return originalIndexName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The full name, including dot path.
|
|
||||||
*/
|
|
||||||
public String fullName() {
|
|
||||||
return fullName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
|
|
||||||
Names names = (Names) o;
|
|
||||||
|
|
||||||
if (!fullName.equals(names.fullName)) return false;
|
|
||||||
if (!indexName.equals(names.indexName)) return false;
|
|
||||||
if (!originalIndexName.equals(names.originalIndexName)) return false;
|
|
||||||
if (!shortName.equals(names.shortName)) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = shortName.hashCode();
|
|
||||||
result = 31 * result + indexName.hashCode();
|
|
||||||
result = 31 * result + originalIndexName.hashCode();
|
|
||||||
result = 31 * result + fullName.hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Loading {
|
|
||||||
LAZY {
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return LAZY_VALUE;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
EAGER {
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return EAGER_VALUE;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
EAGER_GLOBAL_ORDINALS {
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return EAGER_GLOBAL_ORDINALS_VALUE;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static final String KEY = "loading";
|
|
||||||
public static final String EAGER_GLOBAL_ORDINALS_VALUE = "eager_global_ordinals";
|
|
||||||
public static final String EAGER_VALUE = "eager";
|
|
||||||
public static final String LAZY_VALUE = "lazy";
|
|
||||||
|
|
||||||
public static Loading parse(String loading, Loading defaultValue) {
|
|
||||||
if (Strings.isNullOrEmpty(loading)) {
|
|
||||||
return defaultValue;
|
|
||||||
} else if (EAGER_GLOBAL_ORDINALS_VALUE.equalsIgnoreCase(loading)) {
|
|
||||||
return EAGER_GLOBAL_ORDINALS;
|
|
||||||
} else if (EAGER_VALUE.equalsIgnoreCase(loading)) {
|
|
||||||
return EAGER;
|
|
||||||
} else if (LAZY_VALUE.equalsIgnoreCase(loading)) {
|
|
||||||
return LAZY;
|
|
||||||
} else {
|
|
||||||
throw new MapperParsingException("Unknown [" + KEY + "] value: [" + loading + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Names names();
|
|
||||||
|
|
||||||
FieldType fieldType();
|
|
||||||
|
|
||||||
float boost();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The analyzer that will be used to index the field.
|
|
||||||
*/
|
|
||||||
Analyzer indexAnalyzer();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The analyzer that will be used to search the field.
|
|
||||||
*/
|
|
||||||
Analyzer searchAnalyzer();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The analyzer that will be used for quoted search on the field.
|
|
||||||
*/
|
|
||||||
Analyzer searchQuoteAnalyzer();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Similarity used for scoring queries on the field
|
|
||||||
*/
|
|
||||||
SimilarityProvider similarity();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of fields where this field should be copied to
|
* List of fields where this field should be copied to
|
||||||
|
@ -236,18 +92,12 @@ public interface FieldMapper extends Mapper {
|
||||||
@Nullable
|
@Nullable
|
||||||
Query nullValueFilter();
|
Query nullValueFilter();
|
||||||
|
|
||||||
FieldDataType fieldDataType();
|
|
||||||
|
|
||||||
boolean isNumeric();
|
boolean isNumeric();
|
||||||
|
|
||||||
boolean isSortable();
|
boolean isSortable();
|
||||||
|
|
||||||
boolean supportsNullValue();
|
boolean supportsNullValue();
|
||||||
|
|
||||||
boolean hasDocValues();
|
|
||||||
|
|
||||||
Loading normsLoading(Loading defaultLoading);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fields might not be available before indexing, for example _all, token_count,...
|
* Fields might not be available before indexing, for example _all, token_count,...
|
||||||
* When get is called and these fields are requested, this case needs special treatment.
|
* When get is called and these fields are requested, this case needs special treatment.
|
||||||
|
|
|
@ -53,7 +53,7 @@ class FieldMappersLookup implements Iterable<FieldMapper> {
|
||||||
CopyOnWriteHashMap<String, FieldMappers> map = this.mappers;
|
CopyOnWriteHashMap<String, FieldMappers> map = this.mappers;
|
||||||
|
|
||||||
for (FieldMapper mapper : newMappers) {
|
for (FieldMapper mapper : newMappers) {
|
||||||
String key = mapper.names().fullName();
|
String key = mapper.fieldType().names().fullName();
|
||||||
FieldMappers mappers = map.get(key);
|
FieldMappers mappers = map.get(key);
|
||||||
|
|
||||||
if (mappers == null) {
|
if (mappers == null) {
|
||||||
|
@ -76,13 +76,13 @@ class FieldMappersLookup implements Iterable<FieldMapper> {
|
||||||
public FieldMappers indexName(String indexName) {
|
public FieldMappers indexName(String indexName) {
|
||||||
FieldMappers fieldMappers = fullName(indexName);
|
FieldMappers fieldMappers = fullName(indexName);
|
||||||
if (fieldMappers != null) {
|
if (fieldMappers != null) {
|
||||||
if (fieldMappers.mapper().names().indexName().equals(indexName)) {
|
if (fieldMappers.mapper().fieldType().names().indexName().equals(indexName)) {
|
||||||
return fieldMappers;
|
return fieldMappers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fieldMappers = new FieldMappers();
|
fieldMappers = new FieldMappers();
|
||||||
for (FieldMapper mapper : this) {
|
for (FieldMapper mapper : this) {
|
||||||
if (mapper.names().indexName().equals(indexName)) {
|
if (mapper.fieldType().names().indexName().equals(indexName)) {
|
||||||
fieldMappers = fieldMappers.concat(mapper);
|
fieldMappers = fieldMappers.concat(mapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,10 +117,10 @@ class FieldMappersLookup implements Iterable<FieldMapper> {
|
||||||
public Collection<String> simpleMatchToIndexNames(String pattern) {
|
public Collection<String> simpleMatchToIndexNames(String pattern) {
|
||||||
Set<String> fields = Sets.newHashSet();
|
Set<String> fields = Sets.newHashSet();
|
||||||
for (FieldMapper fieldMapper : this) {
|
for (FieldMapper fieldMapper : this) {
|
||||||
if (Regex.simpleMatch(pattern, fieldMapper.names().fullName())) {
|
if (Regex.simpleMatch(pattern, fieldMapper.fieldType().names().fullName())) {
|
||||||
fields.add(fieldMapper.names().indexName());
|
fields.add(fieldMapper.fieldType().names().indexName());
|
||||||
} else if (Regex.simpleMatch(pattern, fieldMapper.names().indexName())) {
|
} else if (Regex.simpleMatch(pattern, fieldMapper.fieldType().names().indexName())) {
|
||||||
fields.add(fieldMapper.names().indexName());
|
fields.add(fieldMapper.fieldType().names().indexName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fields;
|
return fields;
|
||||||
|
@ -132,10 +132,10 @@ class FieldMappersLookup implements Iterable<FieldMapper> {
|
||||||
public Collection<String> simpleMatchToFullName(String pattern) {
|
public Collection<String> simpleMatchToFullName(String pattern) {
|
||||||
Set<String> fields = Sets.newHashSet();
|
Set<String> fields = Sets.newHashSet();
|
||||||
for (FieldMapper fieldMapper : this) {
|
for (FieldMapper fieldMapper : this) {
|
||||||
if (Regex.simpleMatch(pattern, fieldMapper.names().fullName())) {
|
if (Regex.simpleMatch(pattern, fieldMapper.fieldType().names().fullName())) {
|
||||||
fields.add(fieldMapper.names().fullName());
|
fields.add(fieldMapper.fieldType().names().fullName());
|
||||||
} else if (Regex.simpleMatch(pattern, fieldMapper.names().indexName())) {
|
} else if (Regex.simpleMatch(pattern, fieldMapper.fieldType().names().indexName())) {
|
||||||
fields.add(fieldMapper.names().fullName());
|
fields.add(fieldMapper.fieldType().names().fullName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fields;
|
return fields;
|
||||||
|
|
|
@ -0,0 +1,368 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch 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;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
|
import org.apache.lucene.document.FieldType;
|
||||||
|
import org.apache.lucene.index.Term;
|
||||||
|
import org.apache.lucene.index.Terms;
|
||||||
|
import org.apache.lucene.queries.TermsQuery;
|
||||||
|
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.util.BytesRef;
|
||||||
|
import org.elasticsearch.action.fieldstats.FieldStats;
|
||||||
|
import org.elasticsearch.common.Nullable;
|
||||||
|
import org.elasticsearch.common.lucene.BytesRefs;
|
||||||
|
import org.elasticsearch.common.lucene.search.Queries;
|
||||||
|
import org.elasticsearch.common.unit.Fuzziness;
|
||||||
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
|
import org.elasticsearch.index.similarity.SimilarityProvider;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This defines the core properties and functions to operate on a field.
|
||||||
|
*/
|
||||||
|
public class MappedFieldType extends FieldType {
|
||||||
|
|
||||||
|
public static class Names {
|
||||||
|
|
||||||
|
private final String shortName;
|
||||||
|
|
||||||
|
private final String indexName;
|
||||||
|
|
||||||
|
private final String originalIndexName;
|
||||||
|
|
||||||
|
private final String fullName;
|
||||||
|
|
||||||
|
public Names(String name) {
|
||||||
|
this(name, name, name, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Names(String shortName, String indexName, String originalIndexName, String fullName) {
|
||||||
|
this.shortName = shortName;
|
||||||
|
this.indexName = indexName;
|
||||||
|
this.originalIndexName = originalIndexName;
|
||||||
|
this.fullName = fullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The logical name of the field.
|
||||||
|
*/
|
||||||
|
public String shortName() {
|
||||||
|
return shortName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The indexed name of the field. This is the name under which we will
|
||||||
|
* store it in the index.
|
||||||
|
*/
|
||||||
|
public String indexName() {
|
||||||
|
return indexName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The original index name, before any "path" modifications performed on it.
|
||||||
|
*/
|
||||||
|
public String originalIndexName() {
|
||||||
|
return originalIndexName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The full name, including dot path.
|
||||||
|
*/
|
||||||
|
public String fullName() {
|
||||||
|
return fullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
Names names = (Names) o;
|
||||||
|
|
||||||
|
if (!fullName.equals(names.fullName)) return false;
|
||||||
|
if (!indexName.equals(names.indexName)) return false;
|
||||||
|
if (!originalIndexName.equals(names.originalIndexName)) return false;
|
||||||
|
if (!shortName.equals(names.shortName)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = shortName.hashCode();
|
||||||
|
result = 31 * result + indexName.hashCode();
|
||||||
|
result = 31 * result + originalIndexName.hashCode();
|
||||||
|
result = 31 * result + fullName.hashCode();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Loading {
|
||||||
|
LAZY {
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return LAZY_VALUE;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
EAGER {
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return EAGER_VALUE;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
EAGER_GLOBAL_ORDINALS {
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return EAGER_GLOBAL_ORDINALS_VALUE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final String KEY = "loading";
|
||||||
|
public static final String EAGER_GLOBAL_ORDINALS_VALUE = "eager_global_ordinals";
|
||||||
|
public static final String EAGER_VALUE = "eager";
|
||||||
|
public static final String LAZY_VALUE = "lazy";
|
||||||
|
|
||||||
|
public static Loading parse(String loading, Loading defaultValue) {
|
||||||
|
if (Strings.isNullOrEmpty(loading)) {
|
||||||
|
return defaultValue;
|
||||||
|
} else if (EAGER_GLOBAL_ORDINALS_VALUE.equalsIgnoreCase(loading)) {
|
||||||
|
return EAGER_GLOBAL_ORDINALS;
|
||||||
|
} else if (EAGER_VALUE.equalsIgnoreCase(loading)) {
|
||||||
|
return EAGER;
|
||||||
|
} else if (LAZY_VALUE.equalsIgnoreCase(loading)) {
|
||||||
|
return LAZY;
|
||||||
|
} else {
|
||||||
|
throw new MapperParsingException("Unknown [" + KEY + "] value: [" + loading + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Names names;
|
||||||
|
private float boost;
|
||||||
|
// TODO: remove this docvalues flag and use docValuesType
|
||||||
|
private boolean docValues;
|
||||||
|
private NamedAnalyzer indexAnalyzer;
|
||||||
|
private NamedAnalyzer searchAnalyzer;
|
||||||
|
private NamedAnalyzer searchQuoteAnalyzer;
|
||||||
|
private SimilarityProvider similarity;
|
||||||
|
private Loading normsLoading;
|
||||||
|
private FieldDataType fieldDataType;
|
||||||
|
|
||||||
|
protected MappedFieldType(MappedFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
this.names = ref.names();
|
||||||
|
this.boost = ref.boost();
|
||||||
|
this.docValues = ref.hasDocValues();
|
||||||
|
this.indexAnalyzer = ref.indexAnalyzer();
|
||||||
|
this.searchAnalyzer = ref.searchAnalyzer();
|
||||||
|
this.searchQuoteAnalyzer = ref.searchQuoteAnalyzer();
|
||||||
|
this.similarity = ref.similarity();
|
||||||
|
this.normsLoading = ref.normsLoading();
|
||||||
|
this.fieldDataType = ref.fieldDataType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MappedFieldType() {}
|
||||||
|
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new MappedFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNumeric() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSortable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Names names() {
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNames(Names names) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.names = names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float boost() {
|
||||||
|
return boost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBoost(float boost) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.boost = boost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldDataType fieldDataType() {
|
||||||
|
return fieldDataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFieldDataType(FieldDataType fieldDataType) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.fieldDataType = fieldDataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasDocValues() {
|
||||||
|
return docValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHasDocValues(boolean hasDocValues) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.docValues = hasDocValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Loading normsLoading() {
|
||||||
|
return normsLoading;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNormsLoading(Loading normsLoading) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.normsLoading = normsLoading;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamedAnalyzer indexAnalyzer() {
|
||||||
|
return indexAnalyzer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndexAnalyzer(NamedAnalyzer analyzer) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.indexAnalyzer = analyzer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamedAnalyzer searchAnalyzer() {
|
||||||
|
return searchAnalyzer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearchAnalyzer(NamedAnalyzer analyzer) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.searchAnalyzer = analyzer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamedAnalyzer searchQuoteAnalyzer() {
|
||||||
|
return searchQuoteAnalyzer == null ? searchAnalyzer : searchQuoteAnalyzer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearchQuoteAnalyzer(NamedAnalyzer analyzer) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.searchQuoteAnalyzer = analyzer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimilarityProvider similarity() {
|
||||||
|
return similarity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSimilarity(SimilarityProvider similarity) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.similarity = similarity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the actual value of the field. */
|
||||||
|
public Object value(Object value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the value that will be used as a result for search. Can be only of specific types... */
|
||||||
|
public Object valueForSearch(Object value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the indexed value used to construct search "values". */
|
||||||
|
public BytesRef indexedValueForSearch(Object value) {
|
||||||
|
return BytesRefs.toBytesRef(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should the field query {@link #termQuery(Object, org.elasticsearch.index.query.QueryParseContext)} be used when detecting this
|
||||||
|
* field in query string.
|
||||||
|
*/
|
||||||
|
public boolean useTermQueryWithQueryString() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates a term associated with the field of this mapper for the given value */
|
||||||
|
protected Term createTerm(Object value) {
|
||||||
|
return new Term(names().indexName(), indexedValueForSearch(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Query termQuery(Object value, @Nullable QueryParseContext context) {
|
||||||
|
return new TermQuery(createTerm(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Query termsQuery(List values, @Nullable QueryParseContext context) {
|
||||||
|
BytesRef[] bytesRefs = new BytesRef[values.size()];
|
||||||
|
for (int i = 0; i < bytesRefs.length; i++) {
|
||||||
|
bytesRefs[i] = indexedValueForSearch(values.get(i));
|
||||||
|
}
|
||||||
|
return new TermsQuery(names.indexName(), bytesRefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 prefixQuery(Object value, @Nullable MultiTermQuery.RewriteMethod method, @Nullable QueryParseContext context) {
|
||||||
|
PrefixQuery query = new PrefixQuery(createTerm(value));
|
||||||
|
if (method != null) {
|
||||||
|
query.setRewriteMethod(method);
|
||||||
|
}
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Query regexpQuery(Object value, int flags, int maxDeterminizedStates, @Nullable MultiTermQuery.RewriteMethod method, @Nullable QueryParseContext context) {
|
||||||
|
RegexpQuery query = new RegexpQuery(createTerm(value), flags, maxDeterminizedStates);
|
||||||
|
if (method != null) {
|
||||||
|
query.setRewriteMethod(method);
|
||||||
|
}
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a {@link FieldStats} instance that maps to the type of this field based on the provided {@link Terms} instance.
|
||||||
|
*/
|
||||||
|
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
||||||
|
return new FieldStats.Text(
|
||||||
|
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), terms.getMin(), terms.getMax()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A term query to use when parsing a query string. Can return <tt>null</tt>. */
|
||||||
|
@Nullable
|
||||||
|
public Query queryStringTermQuery(Term term) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -690,8 +690,8 @@ public class MapperService extends AbstractIndexComponent {
|
||||||
@Override
|
@Override
|
||||||
protected Analyzer getWrappedAnalyzer(String fieldName) {
|
protected Analyzer getWrappedAnalyzer(String fieldName) {
|
||||||
FieldMapper mapper = smartNameFieldMapper(fieldName);
|
FieldMapper mapper = smartNameFieldMapper(fieldName);
|
||||||
if (mapper != null && mapper.searchAnalyzer() != null) {
|
if (mapper != null && mapper.fieldType().searchAnalyzer() != null) {
|
||||||
return mapper.searchAnalyzer();
|
return mapper.fieldType().searchAnalyzer();
|
||||||
}
|
}
|
||||||
return defaultAnalyzer;
|
return defaultAnalyzer;
|
||||||
}
|
}
|
||||||
|
@ -709,8 +709,8 @@ public class MapperService extends AbstractIndexComponent {
|
||||||
@Override
|
@Override
|
||||||
protected Analyzer getWrappedAnalyzer(String fieldName) {
|
protected Analyzer getWrappedAnalyzer(String fieldName) {
|
||||||
FieldMapper mapper = smartNameFieldMapper(fieldName);
|
FieldMapper mapper = smartNameFieldMapper(fieldName);
|
||||||
if (mapper != null && mapper.searchQuoteAnalyzer() != null) {
|
if (mapper != null && mapper.fieldType().searchQuoteAnalyzer() != null) {
|
||||||
return mapper.searchQuoteAnalyzer();
|
return mapper.fieldType().searchQuoteAnalyzer();
|
||||||
}
|
}
|
||||||
return defaultAnalyzer;
|
return defaultAnalyzer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,28 +25,19 @@ import com.google.common.base.Function;
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Iterators;
|
import com.google.common.collect.Iterators;
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
import org.apache.lucene.document.FieldType;
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
import org.apache.lucene.index.Terms;
|
import org.apache.lucene.index.Terms;
|
||||||
import org.apache.lucene.queries.TermsQuery;
|
|
||||||
import org.apache.lucene.search.FuzzyQuery;
|
|
||||||
import org.apache.lucene.search.MultiTermQuery;
|
import org.apache.lucene.search.MultiTermQuery;
|
||||||
import org.apache.lucene.search.PrefixQuery;
|
|
||||||
import org.apache.lucene.search.Query;
|
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.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.action.fieldstats.FieldStats;
|
import org.elasticsearch.action.fieldstats.FieldStats;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||||
import org.elasticsearch.common.lucene.BytesRefs;
|
|
||||||
import org.elasticsearch.common.lucene.Lucene;
|
import org.elasticsearch.common.lucene.Lucene;
|
||||||
import org.elasticsearch.common.lucene.search.Queries;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.unit.Fuzziness;
|
import org.elasticsearch.common.unit.Fuzziness;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
@ -54,6 +45,7 @@ import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
import org.elasticsearch.index.mapper.ContentPath;
|
import org.elasticsearch.index.mapper.ContentPath;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -74,14 +66,12 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
/**
|
import static org.elasticsearch.index.mapper.core.TypeParsers.DOC_VALUES;
|
||||||
*
|
|
||||||
*/
|
|
||||||
public abstract class AbstractFieldMapper implements FieldMapper {
|
public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
|
|
||||||
public static class Defaults {
|
public static class Defaults {
|
||||||
public static final FieldType FIELD_TYPE = new FieldType();
|
public static final MappedFieldType FIELD_TYPE = new MappedFieldType();
|
||||||
public static final boolean PRE_2X_DOC_VALUES = false;
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setTokenized(true);
|
FIELD_TYPE.setTokenized(true);
|
||||||
|
@ -89,6 +79,7 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
FIELD_TYPE.setStoreTermVectors(false);
|
FIELD_TYPE.setStoreTermVectors(false);
|
||||||
FIELD_TYPE.setOmitNorms(false);
|
FIELD_TYPE.setOmitNorms(false);
|
||||||
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS);
|
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS);
|
||||||
|
FIELD_TYPE.setBoost(Defaults.BOOST);
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,26 +89,21 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
|
|
||||||
public abstract static class Builder<T extends Builder, Y extends AbstractFieldMapper> extends Mapper.Builder<T, Y> {
|
public abstract static class Builder<T extends Builder, Y extends AbstractFieldMapper> extends Mapper.Builder<T, Y> {
|
||||||
|
|
||||||
protected final FieldType fieldType;
|
protected final MappedFieldType fieldType;
|
||||||
private final IndexOptions defaultOptions;
|
private final IndexOptions defaultOptions;
|
||||||
protected Boolean docValues;
|
protected Boolean docValues;
|
||||||
protected float boost = Defaults.BOOST;
|
|
||||||
protected boolean omitNormsSet = false;
|
protected boolean omitNormsSet = false;
|
||||||
protected String indexName;
|
protected String indexName;
|
||||||
protected NamedAnalyzer indexAnalyzer;
|
|
||||||
protected NamedAnalyzer searchAnalyzer;
|
|
||||||
protected Boolean includeInAll;
|
protected Boolean includeInAll;
|
||||||
protected boolean indexOptionsSet = false;
|
protected boolean indexOptionsSet = false;
|
||||||
protected SimilarityProvider similarity;
|
|
||||||
protected Loading normsLoading;
|
|
||||||
@Nullable
|
@Nullable
|
||||||
protected Settings fieldDataSettings;
|
protected Settings fieldDataSettings;
|
||||||
protected final MultiFields.Builder multiFieldsBuilder;
|
protected final MultiFields.Builder multiFieldsBuilder;
|
||||||
protected CopyTo copyTo;
|
protected CopyTo copyTo;
|
||||||
|
|
||||||
protected Builder(String name, FieldType fieldType) {
|
protected Builder(String name, MappedFieldType fieldType) {
|
||||||
super(name);
|
super(name);
|
||||||
this.fieldType = fieldType;
|
this.fieldType = fieldType.clone();
|
||||||
this.defaultOptions = fieldType.indexOptions(); // we have to store it the fieldType is mutable
|
this.defaultOptions = fieldType.indexOptions(); // we have to store it the fieldType is mutable
|
||||||
multiFieldsBuilder = new MultiFields.Builder();
|
multiFieldsBuilder = new MultiFields.Builder();
|
||||||
}
|
}
|
||||||
|
@ -191,7 +177,7 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public T boost(float boost) {
|
public T boost(float boost) {
|
||||||
this.boost = boost;
|
this.fieldType.setBoost(boost);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,12 +199,12 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public T indexAnalyzer(NamedAnalyzer indexAnalyzer) {
|
public T indexAnalyzer(NamedAnalyzer indexAnalyzer) {
|
||||||
this.indexAnalyzer = indexAnalyzer;
|
this.fieldType.setIndexAnalyzer(indexAnalyzer);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T searchAnalyzer(NamedAnalyzer searchAnalyzer) {
|
public T searchAnalyzer(NamedAnalyzer searchAnalyzer) {
|
||||||
this.searchAnalyzer = searchAnalyzer;
|
this.fieldType.setSearchAnalyzer(searchAnalyzer);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,12 +214,12 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public T similarity(SimilarityProvider similarity) {
|
public T similarity(SimilarityProvider similarity) {
|
||||||
this.similarity = similarity;
|
this.fieldType.setSimilarity(similarity);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T normsLoading(Loading normsLoading) {
|
public T normsLoading(MappedFieldType.Loading normsLoading) {
|
||||||
this.normsLoading = normsLoading;
|
this.fieldType.setNormsLoading(normsLoading);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,8 +243,8 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Names buildNames(BuilderContext context) {
|
protected MappedFieldType.Names buildNames(BuilderContext context) {
|
||||||
return new Names(name, buildIndexName(context), buildIndexNameClean(context), buildFullName(context));
|
return new MappedFieldType.Names(name, buildIndexName(context), buildIndexNameClean(context), buildFullName(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String buildIndexName(BuilderContext context) {
|
protected String buildIndexName(BuilderContext context) {
|
||||||
|
@ -279,136 +265,82 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
protected String buildFullName(BuilderContext context) {
|
protected String buildFullName(BuilderContext context) {
|
||||||
return context.path().fullPathAsText(name);
|
return context.path().fullPathAsText(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setupFieldType(BuilderContext context) {
|
||||||
|
fieldType.setNames(buildNames(context));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final Names names;
|
protected MappedFieldType fieldType;
|
||||||
protected float boost;
|
protected final boolean hasDefaultDocValues;
|
||||||
protected FieldType fieldType;
|
|
||||||
protected final Boolean docValues;
|
|
||||||
protected final NamedAnalyzer indexAnalyzer;
|
|
||||||
protected NamedAnalyzer searchAnalyzer;
|
|
||||||
protected final SimilarityProvider similarity;
|
|
||||||
protected Loading normsLoading;
|
|
||||||
protected Settings customFieldDataSettings;
|
protected Settings customFieldDataSettings;
|
||||||
protected FieldDataType fieldDataType;
|
|
||||||
protected final MultiFields multiFields;
|
protected final MultiFields multiFields;
|
||||||
protected CopyTo copyTo;
|
protected CopyTo copyTo;
|
||||||
protected final boolean indexCreatedBefore2x;
|
protected final boolean indexCreatedBefore2x;
|
||||||
|
|
||||||
protected AbstractFieldMapper(Names names, float boost, FieldType fieldType, Boolean docValues, NamedAnalyzer indexAnalyzer,
|
protected AbstractFieldMapper(MappedFieldType fieldType, Boolean docValues, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||||
NamedAnalyzer searchAnalyzer, SimilarityProvider similarity,
|
this(fieldType, docValues, fieldDataSettings, indexSettings, MultiFields.empty(), null);
|
||||||
Loading normsLoading, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
|
||||||
this(names, boost, fieldType, docValues, indexAnalyzer, searchAnalyzer, similarity,
|
|
||||||
normsLoading, fieldDataSettings, indexSettings, MultiFields.empty(), null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AbstractFieldMapper(Names names, float boost, FieldType fieldType, Boolean docValues, NamedAnalyzer indexAnalyzer,
|
protected AbstractFieldMapper(MappedFieldType fieldType, Boolean docValues, @Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||||
NamedAnalyzer searchAnalyzer, SimilarityProvider similarity,
|
|
||||||
Loading normsLoading, @Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
|
||||||
assert indexSettings != null;
|
assert indexSettings != null;
|
||||||
this.names = names;
|
|
||||||
this.boost = boost;
|
|
||||||
this.fieldType = fieldType;
|
|
||||||
this.fieldType.freeze();
|
|
||||||
this.indexCreatedBefore2x = Version.indexCreated(indexSettings).before(Version.V_2_0_0);
|
this.indexCreatedBefore2x = Version.indexCreated(indexSettings).before(Version.V_2_0_0);
|
||||||
|
|
||||||
boolean indexedNotAnalyzed = this.fieldType.tokenized() == false && this.fieldType.indexOptions() != IndexOptions.NONE;
|
|
||||||
if (indexAnalyzer == null && indexedNotAnalyzed) {
|
|
||||||
this.indexAnalyzer = this.searchAnalyzer = Lucene.KEYWORD_ANALYZER;
|
|
||||||
} else {
|
|
||||||
this.indexAnalyzer = indexAnalyzer;
|
|
||||||
this.searchAnalyzer = searchAnalyzer;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.similarity = similarity;
|
|
||||||
this.normsLoading = normsLoading;
|
|
||||||
|
|
||||||
this.customFieldDataSettings = fieldDataSettings;
|
this.customFieldDataSettings = fieldDataSettings;
|
||||||
|
FieldDataType fieldDataType;
|
||||||
if (fieldDataSettings == null) {
|
if (fieldDataSettings == null) {
|
||||||
this.fieldDataType = defaultFieldDataType();
|
fieldDataType = defaultFieldDataType();
|
||||||
} else {
|
} else {
|
||||||
// create a new field data type, with the default settings as well as the "new ones"
|
// create a new field data type, with the default settings as well as the "new ones"
|
||||||
this.fieldDataType = new FieldDataType(defaultFieldDataType().getType(),
|
fieldDataType = new FieldDataType(defaultFieldDataType().getType(),
|
||||||
Settings.builder().put(defaultFieldDataType().getSettings()).put(fieldDataSettings)
|
Settings.builder().put(defaultFieldDataType().getSettings()).put(fieldDataSettings)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (docValues != null) {
|
// TODO: hasDocValues should just be set directly on the field type by callers of this ctor, but
|
||||||
// explicitly set
|
// then we need to eliminate defaultDocValues() (only needed by geo, which needs to be fixed with passing
|
||||||
this.docValues = docValues;
|
// doc values setting down to lat/lon) and get rid of specifying doc values in fielddata (which
|
||||||
} else if (fieldDataType != null && FieldDataType.DOC_VALUES_FORMAT_VALUE.equals(fieldDataType.getFormat(indexSettings))) {
|
// complicates whether we can just compare to the default value to know whether to write the setting)
|
||||||
// convoluted way to enable doc values, should be removed in the future
|
if (docValues == null && fieldDataType != null && FieldDataType.DOC_VALUES_FORMAT_VALUE.equals(fieldDataType.getFormat(indexSettings))) {
|
||||||
this.docValues = true;
|
docValues = true;
|
||||||
} else {
|
|
||||||
this.docValues = null; // use the default
|
|
||||||
}
|
}
|
||||||
|
hasDefaultDocValues = docValues == null;
|
||||||
|
|
||||||
|
this.fieldType = fieldType.clone();
|
||||||
|
if (fieldType.indexAnalyzer() == null && fieldType.tokenized() == false && fieldType.indexOptions() != IndexOptions.NONE) {
|
||||||
|
this.fieldType.setIndexAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
this.fieldType.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
}
|
||||||
|
this.fieldType.setHasDocValues(docValues == null ? defaultDocValues() : docValues);
|
||||||
|
this.fieldType.setFieldDataType(fieldDataType);
|
||||||
|
this.fieldType.freeze();
|
||||||
|
|
||||||
this.multiFields = multiFields;
|
this.multiFields = multiFields;
|
||||||
this.copyTo = copyTo;
|
this.copyTo = copyTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean defaultDocValues() {
|
protected boolean defaultDocValues() {
|
||||||
if (indexCreatedBefore2x) {
|
if (indexCreatedBefore2x) {
|
||||||
return Defaults.PRE_2X_DOC_VALUES;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return fieldType.tokenized() == false && fieldType.indexOptions() != IndexOptions.NONE;
|
return fieldType.tokenized() == false && fieldType.indexOptions() != IndexOptions.NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public final boolean hasDocValues() {
|
|
||||||
return docValues == null ? defaultDocValues() : docValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String name() {
|
public String name() {
|
||||||
// TODO: cleanup names so Mapper knows about paths, so that it is always clear whether we are using short or full name
|
// TODO: cleanup names so Mapper knows about paths, so that it is always clear whether we are using short or full name
|
||||||
return names.shortName();
|
return fieldType.names().shortName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public abstract MappedFieldType defaultFieldType();
|
||||||
public Names names() {
|
|
||||||
return this.names;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract FieldType defaultFieldType();
|
|
||||||
|
|
||||||
public abstract FieldDataType defaultFieldDataType();
|
public abstract FieldDataType defaultFieldDataType();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final FieldDataType fieldDataType() {
|
public MappedFieldType fieldType() {
|
||||||
return fieldDataType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FieldType fieldType() {
|
|
||||||
return fieldType;
|
return fieldType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public float boost() {
|
|
||||||
return this.boost;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Analyzer indexAnalyzer() {
|
|
||||||
return this.indexAnalyzer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Analyzer searchAnalyzer() {
|
|
||||||
return this.searchAnalyzer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Analyzer searchQuoteAnalyzer() {
|
|
||||||
return this.searchAnalyzer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SimilarityProvider similarity() {
|
|
||||||
return similarity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CopyTo copyTo() {
|
public CopyTo copyTo() {
|
||||||
return copyTo;
|
return copyTo;
|
||||||
|
@ -421,12 +353,12 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
parseCreateField(context, fields);
|
parseCreateField(context, fields);
|
||||||
for (Field field : fields) {
|
for (Field field : fields) {
|
||||||
if (!customBoost()) {
|
if (!customBoost()) {
|
||||||
field.setBoost(boost);
|
field.setBoost(fieldType.boost());
|
||||||
}
|
}
|
||||||
context.doc().add(field);
|
context.doc().add(field);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new MapperParsingException("failed to parse [" + names.fullName() + "]", e);
|
throw new MapperParsingException("failed to parse [" + fieldType.names().fullName() + "]", e);
|
||||||
}
|
}
|
||||||
multiFields.parse(this, context);
|
multiFields.parse(this, context);
|
||||||
return null;
|
return null;
|
||||||
|
@ -452,72 +384,59 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object valueForSearch(Object value) {
|
public final Object value(Object value) {
|
||||||
return value;
|
return fieldType().value(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final Object valueForSearch(Object value) {
|
||||||
|
return fieldType().valueForSearch(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: this is not final so ParentFieldMapper can have custom behavior, per type...
|
||||||
@Override
|
@Override
|
||||||
public BytesRef indexedValueForSearch(Object value) {
|
public BytesRef indexedValueForSearch(Object value) {
|
||||||
return BytesRefs.toBytesRef(value);
|
return fieldType().indexedValueForSearch(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query queryStringTermQuery(Term term) {
|
public final Query queryStringTermQuery(Term term) {
|
||||||
return null;
|
return fieldType().queryStringTermQuery(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean useTermQueryWithQueryString() {
|
public final boolean useTermQueryWithQueryString() {
|
||||||
return false;
|
return fieldType().useTermQueryWithQueryString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query termQuery(Object value, @Nullable QueryParseContext context) {
|
public final Query termQuery(Object value, @Nullable QueryParseContext context) {
|
||||||
return new TermQuery(createTerm(value));
|
return fieldType().termQuery(value, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query termsQuery(List values, @Nullable QueryParseContext context) {
|
public final Query termsQuery(List values, @Nullable QueryParseContext context) {
|
||||||
BytesRef[] bytesRefs = new BytesRef[values.size()];
|
return fieldType().termsQuery(values, context);
|
||||||
for (int i = 0; i < bytesRefs.length; i++) {
|
|
||||||
bytesRefs[i] = indexedValueForSearch(values.get(i));
|
|
||||||
}
|
|
||||||
return new TermsQuery(names.indexName(), bytesRefs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
public final Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
||||||
return new TermRangeQuery(names.indexName(),
|
return fieldType().rangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, context);
|
||||||
lowerTerm == null ? null : indexedValueForSearch(lowerTerm),
|
|
||||||
upperTerm == null ? null : indexedValueForSearch(upperTerm),
|
|
||||||
includeLower, includeUpper);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
public final Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
||||||
return new FuzzyQuery(createTerm(value), fuzziness.asDistance(value), prefixLength, maxExpansions, transpositions);
|
return fieldType().fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query prefixQuery(Object value, @Nullable MultiTermQuery.RewriteMethod method, @Nullable QueryParseContext context) {
|
public final Query prefixQuery(Object value, @Nullable MultiTermQuery.RewriteMethod method, @Nullable QueryParseContext context) {
|
||||||
PrefixQuery query = new PrefixQuery(createTerm(value));
|
return fieldType().prefixQuery(value, method, context);
|
||||||
if (method != null) {
|
|
||||||
query.setRewriteMethod(method);
|
|
||||||
}
|
|
||||||
return query;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query regexpQuery(Object value, int flags, int maxDeterminizedStates, @Nullable MultiTermQuery.RewriteMethod method, @Nullable QueryParseContext context) {
|
public final Query regexpQuery(Object value, int flags, int maxDeterminizedStates, @Nullable MultiTermQuery.RewriteMethod method, @Nullable QueryParseContext context) {
|
||||||
RegexpQuery query = new RegexpQuery(createTerm(value), flags, maxDeterminizedStates);
|
return fieldType().regexpQuery(value, flags, maxDeterminizedStates, method, context);
|
||||||
if (method != null) {
|
|
||||||
query.setRewriteMethod(method);
|
|
||||||
}
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Term createTerm(Object value) {
|
|
||||||
return new Term(names.indexName(), indexedValueForSearch(value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -532,7 +451,7 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
if (mergeWith instanceof AbstractFieldMapper) {
|
if (mergeWith instanceof AbstractFieldMapper) {
|
||||||
mergedType = ((AbstractFieldMapper) mergeWith).contentType();
|
mergedType = ((AbstractFieldMapper) mergeWith).contentType();
|
||||||
}
|
}
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] of different type, current_type [" + contentType() + "], merged_type [" + mergedType + "]");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] of different type, current_type [" + contentType() + "], merged_type [" + mergedType + "]");
|
||||||
// different types, return
|
// different types, return
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -540,86 +459,86 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
boolean indexed = fieldType.indexOptions() != IndexOptions.NONE;
|
boolean indexed = fieldType.indexOptions() != IndexOptions.NONE;
|
||||||
boolean mergeWithIndexed = fieldMergeWith.fieldType().indexOptions() != IndexOptions.NONE;
|
boolean mergeWithIndexed = fieldMergeWith.fieldType().indexOptions() != IndexOptions.NONE;
|
||||||
if (indexed != mergeWithIndexed || this.fieldType().tokenized() != fieldMergeWith.fieldType().tokenized()) {
|
if (indexed != mergeWithIndexed || this.fieldType().tokenized() != fieldMergeWith.fieldType().tokenized()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different index values");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different index values");
|
||||||
}
|
}
|
||||||
if (this.fieldType().stored() != fieldMergeWith.fieldType().stored()) {
|
if (this.fieldType().stored() != fieldMergeWith.fieldType().stored()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different store values");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different store values");
|
||||||
}
|
}
|
||||||
if (!this.hasDocValues() && fieldMergeWith.hasDocValues()) {
|
if (!this.fieldType().hasDocValues() && fieldMergeWith.fieldType().hasDocValues()) {
|
||||||
// don't add conflict if this mapper has doc values while the mapper to merge doesn't since doc values are implicitely set
|
// don't add conflict if this mapper has doc values while the mapper to merge doesn't since doc values are implicitely set
|
||||||
// when the doc_values field data format is configured
|
// when the doc_values field data format is configured
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different " + TypeParsers.DOC_VALUES + " values");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different " + TypeParsers.DOC_VALUES + " values");
|
||||||
}
|
}
|
||||||
if (this.fieldType().omitNorms() && !fieldMergeWith.fieldType.omitNorms()) {
|
if (this.fieldType().omitNorms() && !fieldMergeWith.fieldType.omitNorms()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] cannot enable norms (`norms.enabled`)");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] cannot enable norms (`norms.enabled`)");
|
||||||
}
|
}
|
||||||
if (this.fieldType().tokenized() != fieldMergeWith.fieldType().tokenized()) {
|
if (this.fieldType().tokenized() != fieldMergeWith.fieldType().tokenized()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different tokenize values");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different tokenize values");
|
||||||
}
|
}
|
||||||
if (this.fieldType().storeTermVectors() != fieldMergeWith.fieldType().storeTermVectors()) {
|
if (this.fieldType().storeTermVectors() != fieldMergeWith.fieldType().storeTermVectors()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different store_term_vector values");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different store_term_vector values");
|
||||||
}
|
}
|
||||||
if (this.fieldType().storeTermVectorOffsets() != fieldMergeWith.fieldType().storeTermVectorOffsets()) {
|
if (this.fieldType().storeTermVectorOffsets() != fieldMergeWith.fieldType().storeTermVectorOffsets()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different store_term_vector_offsets values");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different store_term_vector_offsets values");
|
||||||
}
|
}
|
||||||
if (this.fieldType().storeTermVectorPositions() != fieldMergeWith.fieldType().storeTermVectorPositions()) {
|
if (this.fieldType().storeTermVectorPositions() != fieldMergeWith.fieldType().storeTermVectorPositions()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different store_term_vector_positions values");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different store_term_vector_positions values");
|
||||||
}
|
}
|
||||||
if (this.fieldType().storeTermVectorPayloads() != fieldMergeWith.fieldType().storeTermVectorPayloads()) {
|
if (this.fieldType().storeTermVectorPayloads() != fieldMergeWith.fieldType().storeTermVectorPayloads()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different store_term_vector_payloads values");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different store_term_vector_payloads values");
|
||||||
}
|
}
|
||||||
|
|
||||||
// null and "default"-named index analyzers both mean the default is used
|
// null and "default"-named index analyzers both mean the default is used
|
||||||
if (this.indexAnalyzer == null || "default".equals(this.indexAnalyzer.name())) {
|
if (this.fieldType.indexAnalyzer() == null || "default".equals(this.fieldType.indexAnalyzer().name())) {
|
||||||
if (fieldMergeWith.indexAnalyzer != null && !"default".equals(fieldMergeWith.indexAnalyzer.name())) {
|
if (fieldMergeWith.fieldType.indexAnalyzer() != null && "default".equals(fieldMergeWith.fieldType.indexAnalyzer().name()) == false) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different analyzer");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different analyzer");
|
||||||
}
|
}
|
||||||
} else if (fieldMergeWith.indexAnalyzer == null || "default".equals(fieldMergeWith.indexAnalyzer.name())) {
|
} else if (fieldMergeWith.fieldType.indexAnalyzer() == null || "default".equals(fieldMergeWith.fieldType.indexAnalyzer().name())) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different analyzer");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different analyzer");
|
||||||
} else if (!this.indexAnalyzer.name().equals(fieldMergeWith.indexAnalyzer.name())) {
|
} else if (this.fieldType.indexAnalyzer().name().equals(fieldMergeWith.fieldType.indexAnalyzer().name()) == false) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different analyzer");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different analyzer");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.names().equals(fieldMergeWith.names())) {
|
if (!this.fieldType().names().equals(fieldMergeWith.fieldType().names())) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different index_name");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different index_name");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.similarity == null) {
|
if (this.fieldType.similarity() == null) {
|
||||||
if (fieldMergeWith.similarity() != null) {
|
if (fieldMergeWith.fieldType.similarity() != null) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different similarity");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different similarity");
|
||||||
}
|
}
|
||||||
} else if (fieldMergeWith.similarity() == null) {
|
} else if (fieldMergeWith.fieldType().similarity() == null) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different similarity");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different similarity");
|
||||||
} else if (!this.similarity().equals(fieldMergeWith.similarity())) {
|
} else if (!this.fieldType().similarity().equals(fieldMergeWith.fieldType().similarity())) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different similarity");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different similarity");
|
||||||
}
|
}
|
||||||
multiFields.merge(mergeWith, mergeResult);
|
multiFields.merge(mergeWith, mergeResult);
|
||||||
|
|
||||||
if (!mergeResult.simulate()) {
|
if (!mergeResult.simulate()) {
|
||||||
// apply changeable values
|
// apply changeable values
|
||||||
this.fieldType = new FieldType(this.fieldType);
|
this.fieldType = this.fieldType.clone();
|
||||||
this.fieldType.setOmitNorms(fieldMergeWith.fieldType.omitNorms());
|
this.fieldType.setOmitNorms(fieldMergeWith.fieldType.omitNorms());
|
||||||
this.fieldType.freeze();
|
this.fieldType.setBoost(fieldMergeWith.fieldType.boost());
|
||||||
this.boost = fieldMergeWith.boost;
|
this.fieldType.setNormsLoading(fieldMergeWith.fieldType.normsLoading());
|
||||||
this.normsLoading = fieldMergeWith.normsLoading;
|
if (fieldMergeWith.fieldType.searchAnalyzer() != null) {
|
||||||
this.copyTo = fieldMergeWith.copyTo;
|
this.fieldType.setSearchAnalyzer(fieldMergeWith.fieldType.searchAnalyzer());
|
||||||
if (fieldMergeWith.searchAnalyzer != null) {
|
|
||||||
this.searchAnalyzer = fieldMergeWith.searchAnalyzer;
|
|
||||||
}
|
}
|
||||||
if (fieldMergeWith.customFieldDataSettings != null) {
|
if (fieldMergeWith.customFieldDataSettings != null) {
|
||||||
if (!Objects.equal(fieldMergeWith.customFieldDataSettings, this.customFieldDataSettings)) {
|
if (!Objects.equal(fieldMergeWith.customFieldDataSettings, this.customFieldDataSettings)) {
|
||||||
this.customFieldDataSettings = fieldMergeWith.customFieldDataSettings;
|
this.customFieldDataSettings = fieldMergeWith.customFieldDataSettings;
|
||||||
this.fieldDataType = new FieldDataType(defaultFieldDataType().getType(),
|
this.fieldType.setFieldDataType(new FieldDataType(defaultFieldDataType().getType(),
|
||||||
Settings.builder().put(defaultFieldDataType().getSettings()).put(this.customFieldDataSettings)
|
Settings.builder().put(defaultFieldDataType().getSettings()).put(this.customFieldDataSettings)
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.fieldType.freeze();
|
||||||
|
this.copyTo = fieldMergeWith.copyTo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject(names.shortName());
|
builder.startObject(fieldType.names().shortName());
|
||||||
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
boolean includeDefaults = params.paramAsBoolean("include_defaults", false);
|
||||||
doXContentBody(builder, includeDefaults, params);
|
doXContentBody(builder, includeDefaults, params);
|
||||||
return builder.endObject();
|
return builder.endObject();
|
||||||
|
@ -628,12 +547,12 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||||
|
|
||||||
builder.field("type", contentType());
|
builder.field("type", contentType());
|
||||||
if (indexCreatedBefore2x && (includeDefaults || !names.shortName().equals(names.originalIndexName()))) {
|
if (indexCreatedBefore2x && (includeDefaults || !fieldType.names().shortName().equals(fieldType.names().originalIndexName()))) {
|
||||||
builder.field("index_name", names.originalIndexName());
|
builder.field("index_name", fieldType.names().originalIndexName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (includeDefaults || boost != 1.0f) {
|
if (includeDefaults || fieldType.boost() != 1.0f) {
|
||||||
builder.field("boost", boost);
|
builder.field("boost", fieldType.boost());
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldType defaultFieldType = defaultFieldType();
|
FieldType defaultFieldType = defaultFieldType();
|
||||||
|
@ -650,13 +569,13 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
if (includeDefaults || fieldType.storeTermVectors() != defaultFieldType.storeTermVectors()) {
|
if (includeDefaults || fieldType.storeTermVectors() != defaultFieldType.storeTermVectors()) {
|
||||||
builder.field("term_vector", termVectorOptionsToString(fieldType));
|
builder.field("term_vector", termVectorOptionsToString(fieldType));
|
||||||
}
|
}
|
||||||
if (includeDefaults || fieldType.omitNorms() != defaultFieldType.omitNorms() || normsLoading != null) {
|
if (includeDefaults || fieldType.omitNorms() != defaultFieldType.omitNorms() || fieldType.normsLoading() != null) {
|
||||||
builder.startObject("norms");
|
builder.startObject("norms");
|
||||||
if (includeDefaults || fieldType.omitNorms() != defaultFieldType.omitNorms()) {
|
if (includeDefaults || fieldType.omitNorms() != defaultFieldType.omitNorms()) {
|
||||||
builder.field("enabled", !fieldType.omitNorms());
|
builder.field("enabled", !fieldType.omitNorms());
|
||||||
}
|
}
|
||||||
if (normsLoading != null) {
|
if (fieldType.normsLoading() != null) {
|
||||||
builder.field(Loading.KEY, normsLoading);
|
builder.field(MappedFieldType.Loading.KEY, fieldType.normsLoading());
|
||||||
}
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
|
@ -666,8 +585,8 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
|
|
||||||
doXContentAnalyzers(builder, includeDefaults);
|
doXContentAnalyzers(builder, includeDefaults);
|
||||||
|
|
||||||
if (similarity() != null) {
|
if (fieldType().similarity() != null) {
|
||||||
builder.field("similarity", similarity().name());
|
builder.field("similarity", fieldType().similarity().name());
|
||||||
} else if (includeDefaults) {
|
} else if (includeDefaults) {
|
||||||
builder.field("similarity", SimilarityLookupService.DEFAULT_SIMILARITY);
|
builder.field("similarity", SimilarityLookupService.DEFAULT_SIMILARITY);
|
||||||
}
|
}
|
||||||
|
@ -677,7 +596,7 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
orderedFielddataSettings.putAll(customFieldDataSettings.getAsMap());
|
orderedFielddataSettings.putAll(customFieldDataSettings.getAsMap());
|
||||||
builder.field("fielddata", orderedFielddataSettings);
|
builder.field("fielddata", orderedFielddataSettings);
|
||||||
} else if (includeDefaults) {
|
} else if (includeDefaults) {
|
||||||
orderedFielddataSettings.putAll(fieldDataType.getSettings().getAsMap());
|
orderedFielddataSettings.putAll(fieldType.fieldDataType().getSettings().getAsMap());
|
||||||
builder.field("fielddata", orderedFielddataSettings);
|
builder.field("fielddata", orderedFielddataSettings);
|
||||||
}
|
}
|
||||||
multiFields.toXContent(builder, params);
|
multiFields.toXContent(builder, params);
|
||||||
|
@ -688,21 +607,21 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doXContentAnalyzers(XContentBuilder builder, boolean includeDefaults) throws IOException {
|
protected void doXContentAnalyzers(XContentBuilder builder, boolean includeDefaults) throws IOException {
|
||||||
if (indexAnalyzer == null) {
|
if (fieldType.indexAnalyzer() == null) {
|
||||||
if (includeDefaults) {
|
if (includeDefaults) {
|
||||||
builder.field("analyzer", "default");
|
builder.field("analyzer", "default");
|
||||||
}
|
}
|
||||||
} else if (includeDefaults || indexAnalyzer.name().startsWith("_") == false && indexAnalyzer.name().equals("default") == false) {
|
} else if (includeDefaults || fieldType.indexAnalyzer().name().startsWith("_") == false && fieldType.indexAnalyzer().name().equals("default") == false) {
|
||||||
builder.field("analyzer", indexAnalyzer.name());
|
builder.field("analyzer", fieldType.indexAnalyzer().name());
|
||||||
if (searchAnalyzer.name().equals(indexAnalyzer.name()) == false) {
|
if (fieldType.searchAnalyzer().name().equals(fieldType.indexAnalyzer().name()) == false) {
|
||||||
builder.field("search_analyzer", searchAnalyzer.name());
|
builder.field("search_analyzer", fieldType.searchAnalyzer().name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doXContentDocValues(XContentBuilder builder, boolean includeDefaults) throws IOException {
|
protected void doXContentDocValues(XContentBuilder builder, boolean includeDefaults) throws IOException {
|
||||||
if (includeDefaults || docValues != null) {
|
if (includeDefaults || hasDefaultDocValues == false) {
|
||||||
builder.field(TypeParsers.DOC_VALUES, hasDocValues());
|
builder.field(DOC_VALUES, fieldType().hasDocValues());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -753,7 +672,6 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected abstract String contentType();
|
protected abstract String contentType();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -762,13 +680,13 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNumeric() {
|
public final boolean isNumeric() {
|
||||||
return false;
|
return fieldType().isNumeric();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSortable() {
|
public final boolean isSortable() {
|
||||||
return true;
|
return fieldType().isSortable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -776,11 +694,6 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Loading normsLoading(Loading defaultLoading) {
|
|
||||||
return normsLoading == null ? defaultLoading : normsLoading;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class MultiFields {
|
public static class MultiFields {
|
||||||
|
|
||||||
public static MultiFields empty() {
|
public static MultiFields empty() {
|
||||||
|
@ -854,7 +767,7 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
ContentPath.Type origPathType = context.path().pathType();
|
ContentPath.Type origPathType = context.path().pathType();
|
||||||
context.path().pathType(pathType);
|
context.path().pathType(pathType);
|
||||||
|
|
||||||
context.path().add(mainField.names().shortName());
|
context.path().add(mainField.fieldType().names().shortName());
|
||||||
for (ObjectCursor<FieldMapper> cursor : mappers.values()) {
|
for (ObjectCursor<FieldMapper> cursor : mappers.values()) {
|
||||||
cursor.value.parse(context);
|
cursor.value.parse(context);
|
||||||
}
|
}
|
||||||
|
@ -871,7 +784,7 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
|
|
||||||
for (ObjectCursor<FieldMapper> cursor : mergeWithMultiField.multiFields.mappers.values()) {
|
for (ObjectCursor<FieldMapper> cursor : mergeWithMultiField.multiFields.mappers.values()) {
|
||||||
FieldMapper mergeWithMapper = cursor.value;
|
FieldMapper mergeWithMapper = cursor.value;
|
||||||
Mapper mergeIntoMapper = mappers.get(mergeWithMapper.names().shortName());
|
Mapper mergeIntoMapper = mappers.get(mergeWithMapper.fieldType().names().shortName());
|
||||||
if (mergeIntoMapper == null) {
|
if (mergeIntoMapper == null) {
|
||||||
// no mapping, simply add it if not simulating
|
// no mapping, simply add it if not simulating
|
||||||
if (!mergeResult.simulate()) {
|
if (!mergeResult.simulate()) {
|
||||||
|
@ -882,7 +795,7 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
if (newMappersBuilder == null) {
|
if (newMappersBuilder == null) {
|
||||||
newMappersBuilder = ImmutableOpenMap.builder(mappers);
|
newMappersBuilder = ImmutableOpenMap.builder(mappers);
|
||||||
}
|
}
|
||||||
newMappersBuilder.put(mergeWithMapper.names().shortName(), mergeWithMapper);
|
newMappersBuilder.put(mergeWithMapper.fieldType().names().shortName(), mergeWithMapper);
|
||||||
if (mergeWithMapper instanceof AbstractFieldMapper) {
|
if (mergeWithMapper instanceof AbstractFieldMapper) {
|
||||||
if (newFieldMappers == null) {
|
if (newFieldMappers == null) {
|
||||||
newFieldMappers = new ArrayList<>(2);
|
newFieldMappers = new ArrayList<>(2);
|
||||||
|
@ -992,9 +905,7 @@ public abstract class AbstractFieldMapper implements FieldMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
public final FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
||||||
return new FieldStats.Text(
|
return fieldType().stats(terms, maxDoc);
|
||||||
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), terms.getMin(), terms.getMax()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.index.mapper.core;
|
package org.elasticsearch.index.mapper.core;
|
||||||
|
|
||||||
import com.carrotsearch.hppc.ObjectArrayList;
|
import com.carrotsearch.hppc.ObjectArrayList;
|
||||||
|
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
import org.apache.lucene.document.FieldType;
|
||||||
import org.apache.lucene.index.DocValuesType;
|
import org.apache.lucene.index.DocValuesType;
|
||||||
|
@ -40,6 +39,7 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.CollectionUtils;
|
import org.elasticsearch.common.util.CollectionUtils;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
|
@ -63,7 +63,7 @@ public class BinaryFieldMapper extends AbstractFieldMapper {
|
||||||
|
|
||||||
|
|
||||||
public static class Defaults extends AbstractFieldMapper.Defaults {
|
public static class Defaults extends AbstractFieldMapper.Defaults {
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new BinaryFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setIndexOptions(IndexOptions.NONE);
|
FIELD_TYPE.setIndexOptions(IndexOptions.NONE);
|
||||||
|
@ -74,13 +74,15 @@ public class BinaryFieldMapper extends AbstractFieldMapper {
|
||||||
public static class Builder extends AbstractFieldMapper.Builder<Builder, BinaryFieldMapper> {
|
public static class Builder extends AbstractFieldMapper.Builder<Builder, BinaryFieldMapper> {
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE));
|
super(name, Defaults.FIELD_TYPE);
|
||||||
builder = this;
|
builder = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BinaryFieldMapper build(BuilderContext context) {
|
public BinaryFieldMapper build(BuilderContext context) {
|
||||||
return new BinaryFieldMapper(buildNames(context), fieldType, docValues,
|
setupFieldType(context);
|
||||||
|
((BinaryFieldType)fieldType).tryUncompressing = context.indexCreatedVersion().before(Version.V_2_0_0);
|
||||||
|
return new BinaryFieldMapper(fieldType, docValues,
|
||||||
fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,13 +104,67 @@ public class BinaryFieldMapper extends AbstractFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BinaryFieldMapper(Names names, FieldType fieldType, Boolean docValues,
|
public static class BinaryFieldType extends MappedFieldType {
|
||||||
|
protected boolean tryUncompressing = false;
|
||||||
|
|
||||||
|
public BinaryFieldType() {
|
||||||
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BinaryFieldType(BinaryFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
this.tryUncompressing = ref.tryUncompressing;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new BinaryFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BytesReference value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
BytesReference bytes;
|
||||||
|
if (value instanceof BytesRef) {
|
||||||
|
bytes = new BytesArray((BytesRef) value);
|
||||||
|
} else if (value instanceof BytesReference) {
|
||||||
|
bytes = (BytesReference) value;
|
||||||
|
} else if (value instanceof byte[]) {
|
||||||
|
bytes = new BytesArray((byte[]) value);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
bytes = new BytesArray(Base64.decode(value.toString()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ElasticsearchParseException("failed to convert bytes", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (tryUncompressing) { // backcompat behavior
|
||||||
|
return CompressorFactory.uncompressIfNeeded(bytes);
|
||||||
|
} else {
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ElasticsearchParseException("failed to decompress source", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object valueForSearch(Object value) {
|
||||||
|
return value(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BinaryFieldMapper(MappedFieldType fieldType, Boolean docValues,
|
||||||
@Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
@Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||||
super(names, 1.0f, fieldType, docValues, null, null, null, null, fieldDataSettings, indexSettings, multiFields, copyTo);
|
super(fieldType, docValues, fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,45 +173,9 @@ public class BinaryFieldMapper extends AbstractFieldMapper {
|
||||||
return new FieldDataType("binary");
|
return new FieldDataType("binary");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object valueForSearch(Object value) {
|
|
||||||
return value(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BytesReference value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
BytesReference bytes;
|
|
||||||
if (value instanceof BytesRef) {
|
|
||||||
bytes = new BytesArray((BytesRef) value);
|
|
||||||
} else if (value instanceof BytesReference) {
|
|
||||||
bytes = (BytesReference) value;
|
|
||||||
} else if (value instanceof byte[]) {
|
|
||||||
bytes = new BytesArray((byte[]) value);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
bytes = new BytesArray(Base64.decode(value.toString()));
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new ElasticsearchParseException("failed to convert bytes", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (indexCreatedBefore2x) {
|
|
||||||
return CompressorFactory.uncompressIfNeeded(bytes);
|
|
||||||
} else {
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new ElasticsearchParseException("failed to decompress source", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void parseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
protected void parseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
||||||
if (!fieldType().stored() && !hasDocValues()) {
|
if (!fieldType().stored() && !fieldType().hasDocValues()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
byte[] value = context.parseExternalValue(byte[].class);
|
byte[] value = context.parseExternalValue(byte[].class);
|
||||||
|
@ -170,14 +190,14 @@ public class BinaryFieldMapper extends AbstractFieldMapper {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fieldType().stored()) {
|
if (fieldType().stored()) {
|
||||||
fields.add(new Field(names.indexName(), value, fieldType));
|
fields.add(new Field(fieldType().names().indexName(), value, fieldType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
CustomBinaryDocValuesField field = (CustomBinaryDocValuesField) context.doc().getByKey(names().indexName());
|
CustomBinaryDocValuesField field = (CustomBinaryDocValuesField) context.doc().getByKey(fieldType().names().indexName());
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
field = new CustomBinaryDocValuesField(names().indexName(), value);
|
field = new CustomBinaryDocValuesField(fieldType().names().indexName(), value);
|
||||||
context.doc().addWithKey(names().indexName(), field);
|
context.doc().addWithKey(fieldType().names().indexName(), field);
|
||||||
} else {
|
} else {
|
||||||
field.add(value);
|
field.add(value);
|
||||||
}
|
}
|
||||||
|
@ -192,17 +212,11 @@ public class BinaryFieldMapper extends AbstractFieldMapper {
|
||||||
|
|
||||||
public static class CustomBinaryDocValuesField extends NumberFieldMapper.CustomNumericDocValuesField {
|
public static class CustomBinaryDocValuesField extends NumberFieldMapper.CustomNumericDocValuesField {
|
||||||
|
|
||||||
public static final FieldType TYPE = new FieldType();
|
|
||||||
static {
|
|
||||||
TYPE.setDocValuesType(DocValuesType.BINARY);
|
|
||||||
TYPE.freeze();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ObjectArrayList<byte[]> bytesList;
|
private final ObjectArrayList<byte[]> bytesList;
|
||||||
|
|
||||||
private int totalSize = 0;
|
private int totalSize = 0;
|
||||||
|
|
||||||
public CustomBinaryDocValuesField(String name, byte[] bytes) {
|
public CustomBinaryDocValuesField(String name, byte[] bytes) {
|
||||||
super(name);
|
super(name);
|
||||||
bytesList = new ObjectArrayList<>();
|
bytesList = new ObjectArrayList<>();
|
||||||
add(bytes);
|
add(bytes);
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.index.mapper.core;
|
package org.elasticsearch.index.mapper.core;
|
||||||
|
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.document.SortedNumericDocValuesField;
|
import org.apache.lucene.document.SortedNumericDocValuesField;
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.search.ConstantScoreQuery;
|
import org.apache.lucene.search.ConstantScoreQuery;
|
||||||
|
@ -34,6 +33,7 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -58,12 +58,14 @@ public class BooleanFieldMapper extends AbstractFieldMapper {
|
||||||
public static final String CONTENT_TYPE = "boolean";
|
public static final String CONTENT_TYPE = "boolean";
|
||||||
|
|
||||||
public static class Defaults extends AbstractFieldMapper.Defaults {
|
public static class Defaults extends AbstractFieldMapper.Defaults {
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new BooleanFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setOmitNorms(true);
|
FIELD_TYPE.setOmitNorms(true);
|
||||||
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
||||||
FIELD_TYPE.setTokenized(false);
|
FIELD_TYPE.setTokenized(false);
|
||||||
|
FIELD_TYPE.setIndexAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +82,7 @@ public class BooleanFieldMapper extends AbstractFieldMapper {
|
||||||
private Boolean nullValue = Defaults.NULL_VALUE;
|
private Boolean nullValue = Defaults.NULL_VALUE;
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE));
|
super(name, Defaults.FIELD_TYPE);
|
||||||
this.builder = this;
|
this.builder = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,8 +101,9 @@ public class BooleanFieldMapper extends AbstractFieldMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BooleanFieldMapper build(BuilderContext context) {
|
public BooleanFieldMapper build(BuilderContext context) {
|
||||||
return new BooleanFieldMapper(buildNames(context), boost, fieldType, docValues, nullValue,
|
setupFieldType(context);
|
||||||
similarity, normsLoading, fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
return new BooleanFieldMapper(fieldType, docValues, nullValue,
|
||||||
|
fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,17 +128,86 @@ public class BooleanFieldMapper extends AbstractFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class BooleanFieldType extends MappedFieldType {
|
||||||
|
|
||||||
|
public BooleanFieldType() {
|
||||||
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BooleanFieldType(BooleanFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new BooleanFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BytesRef indexedValueForSearch(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return Values.FALSE;
|
||||||
|
}
|
||||||
|
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 (sValue.length() == 1 && sValue.charAt(0) == 'F') {
|
||||||
|
return Values.FALSE;
|
||||||
|
}
|
||||||
|
if (Booleans.parseBoolean(sValue, false)) {
|
||||||
|
return Values.TRUE;
|
||||||
|
}
|
||||||
|
return Values.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return Boolean.FALSE;
|
||||||
|
}
|
||||||
|
String sValue = value.toString();
|
||||||
|
if (sValue.length() == 0) {
|
||||||
|
return Boolean.FALSE;
|
||||||
|
}
|
||||||
|
if (sValue.length() == 1 && sValue.charAt(0) == 'F') {
|
||||||
|
return Boolean.FALSE;
|
||||||
|
}
|
||||||
|
if (Booleans.parseBoolean(sValue, false)) {
|
||||||
|
return Boolean.TRUE;
|
||||||
|
}
|
||||||
|
return Boolean.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object valueForSearch(Object value) {
|
||||||
|
return value(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useTermQueryWithQueryString() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Boolean nullValue;
|
private Boolean nullValue;
|
||||||
|
|
||||||
protected BooleanFieldMapper(Names names, float boost, FieldType fieldType, Boolean docValues, Boolean nullValue,
|
protected BooleanFieldMapper(MappedFieldType fieldType, Boolean docValues, Boolean nullValue,
|
||||||
SimilarityProvider similarity, Loading normsLoading,
|
|
||||||
@Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
@Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||||
super(names, boost, fieldType, docValues, Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER, similarity, normsLoading, fieldDataSettings, indexSettings, multiFields, copyTo);
|
super(fieldType, docValues, fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||||
this.nullValue = nullValue;
|
this.nullValue = nullValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,60 +217,6 @@ public class BooleanFieldMapper extends AbstractFieldMapper {
|
||||||
return new FieldDataType(CONTENT_TYPE);
|
return new FieldDataType(CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean useTermQueryWithQueryString() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return Boolean.FALSE;
|
|
||||||
}
|
|
||||||
String sValue = value.toString();
|
|
||||||
if (sValue.length() == 0) {
|
|
||||||
return Boolean.FALSE;
|
|
||||||
}
|
|
||||||
if (sValue.length() == 1 && sValue.charAt(0) == 'F') {
|
|
||||||
return Boolean.FALSE;
|
|
||||||
}
|
|
||||||
if (Booleans.parseBoolean(sValue, false)) {
|
|
||||||
return Boolean.TRUE;
|
|
||||||
}
|
|
||||||
return Boolean.FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object valueForSearch(Object value) {
|
|
||||||
return value(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BytesRef indexedValueForSearch(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return Values.FALSE;
|
|
||||||
}
|
|
||||||
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 (sValue.length() == 1 && sValue.charAt(0) == 'F') {
|
|
||||||
return Values.FALSE;
|
|
||||||
}
|
|
||||||
if (Booleans.parseBoolean(sValue, false)) {
|
|
||||||
return Values.TRUE;
|
|
||||||
}
|
|
||||||
return Values.FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query nullValueFilter() {
|
public Query nullValueFilter() {
|
||||||
if (nullValue == null) {
|
if (nullValue == null) {
|
||||||
|
@ -209,7 +227,7 @@ public class BooleanFieldMapper extends AbstractFieldMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void parseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
protected void parseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
||||||
if (fieldType().indexOptions() == IndexOptions.NONE && !fieldType().stored() && !hasDocValues()) {
|
if (fieldType().indexOptions() == IndexOptions.NONE && !fieldType().stored() && !fieldType().hasDocValues()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,9 +246,9 @@ public class BooleanFieldMapper extends AbstractFieldMapper {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fields.add(new Field(names.indexName(), value ? "T" : "F", fieldType));
|
fields.add(new Field(fieldType.names().indexName(), value ? "T" : "F", fieldType));
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
fields.add(new SortedNumericDocValuesField(names.indexName(), value ? 1 : 0));
|
fields.add(new SortedNumericDocValuesField(fieldType.names().indexName(), value ? 1 : 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ package org.elasticsearch.index.mapper.core;
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.index.Terms;
|
import org.apache.lucene.index.Terms;
|
||||||
import org.apache.lucene.search.ConstantScoreQuery;
|
import org.apache.lucene.search.ConstantScoreQuery;
|
||||||
|
@ -41,13 +40,13 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
import org.elasticsearch.index.analysis.NumericIntegerAnalyzer;
|
import org.elasticsearch.index.analysis.NumericIntegerAnalyzer;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
import org.elasticsearch.index.mapper.MergeResult;
|
import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -66,7 +65,7 @@ public class ByteFieldMapper extends NumberFieldMapper {
|
||||||
public static final String CONTENT_TYPE = "byte";
|
public static final String CONTENT_TYPE = "byte";
|
||||||
|
|
||||||
public static class Defaults extends NumberFieldMapper.Defaults {
|
public static class Defaults extends NumberFieldMapper.Defaults {
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(NumberFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new ByteFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
|
@ -80,7 +79,7 @@ public class ByteFieldMapper extends NumberFieldMapper {
|
||||||
protected Byte nullValue = Defaults.NULL_VALUE;
|
protected Byte nullValue = Defaults.NULL_VALUE;
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_8_BIT);
|
super(name, Defaults.FIELD_TYPE, Defaults.PRECISION_STEP_8_BIT);
|
||||||
builder = this;
|
builder = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,14 +90,23 @@ public class ByteFieldMapper extends NumberFieldMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteFieldMapper build(BuilderContext context) {
|
public ByteFieldMapper build(BuilderContext context) {
|
||||||
fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
|
setupFieldType(context);
|
||||||
ByteFieldMapper fieldMapper = new ByteFieldMapper(buildNames(context),
|
ByteFieldMapper fieldMapper = new ByteFieldMapper(fieldType, docValues, nullValue, ignoreMalformed(context),
|
||||||
fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue, ignoreMalformed(context),
|
coerce(context), fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
||||||
coerce(context), similarity, normsLoading,
|
|
||||||
fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
|
||||||
fieldMapper.includeInAll(includeInAll);
|
fieldMapper.includeInAll(includeInAll);
|
||||||
return fieldMapper;
|
return fieldMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NamedAnalyzer makeNumberAnalyzer(int precisionStep) {
|
||||||
|
String name = precisionStep == Integer.MAX_VALUE ? "_byte/max" : ("_byte/" + precisionStep);
|
||||||
|
return new NamedAnalyzer(name, new NumericIntegerAnalyzer(precisionStep));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int maxPrecisionStep() {
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TypeParser implements Mapper.TypeParser {
|
public static class TypeParser implements Mapper.TypeParser {
|
||||||
|
@ -122,24 +130,81 @@ public class ByteFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ByteFieldType extends NumberFieldType {
|
||||||
|
public ByteFieldType() {}
|
||||||
|
|
||||||
|
protected ByteFieldType(ByteFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NumberFieldType clone() {
|
||||||
|
return new ByteFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Byte value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).byteValue();
|
||||||
|
}
|
||||||
|
if (value instanceof BytesRef) {
|
||||||
|
return ((BytesRef) value).bytes[((BytesRef) value).offset];
|
||||||
|
}
|
||||||
|
return Byte.parseByte(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BytesRef indexedValueForSearch(Object value) {
|
||||||
|
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
||||||
|
NumericUtils.intToPrefixCoded(parseValue(value), 0, bytesRef); // 0 because of exact match
|
||||||
|
return bytesRef.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
||||||
|
return NumericRangeQuery.newIntRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
lowerTerm == null ? null : (int)parseValue(lowerTerm),
|
||||||
|
upperTerm == null ? null : (int)parseValue(upperTerm),
|
||||||
|
includeLower, includeUpper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
||||||
|
byte iValue = Byte.parseByte(value);
|
||||||
|
byte iSim = fuzziness.asByte();
|
||||||
|
return NumericRangeQuery.newIntRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
iValue - iSim,
|
||||||
|
iValue + iSim,
|
||||||
|
true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
||||||
|
long minValue = NumericUtils.getMinInt(terms);
|
||||||
|
long maxValue = NumericUtils.getMaxInt(terms);
|
||||||
|
return new FieldStats.Long(
|
||||||
|
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), minValue, maxValue
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Byte nullValue;
|
private Byte nullValue;
|
||||||
|
|
||||||
private String nullValueAsString;
|
private String nullValueAsString;
|
||||||
|
|
||||||
protected ByteFieldMapper(Names names, int precisionStep, float boost, FieldType fieldType, Boolean docValues,
|
protected ByteFieldMapper(MappedFieldType fieldType, Boolean docValues,
|
||||||
Byte nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
Byte nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
||||||
SimilarityProvider similarity, Loading normsLoading,
|
|
||||||
@Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
@Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||||
super(names, precisionStep, boost, fieldType, docValues,
|
super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||||
ignoreMalformed, coerce, new NamedAnalyzer("_byte/" + precisionStep, new NumericIntegerAnalyzer(precisionStep)),
|
|
||||||
new NamedAnalyzer("_byte/max", new NumericIntegerAnalyzer(Integer.MAX_VALUE)),
|
|
||||||
similarity, normsLoading, fieldDataSettings, indexSettings, multiFields, copyTo);
|
|
||||||
this.nullValue = nullValue;
|
this.nullValue = nullValue;
|
||||||
this.nullValueAsString = nullValue == null ? null : nullValue.toString();
|
this.nullValueAsString = nullValue == null ? null : nullValue.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,33 +213,7 @@ public class ByteFieldMapper extends NumberFieldMapper {
|
||||||
return new FieldDataType("byte");
|
return new FieldDataType("byte");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private static byte parseValue(Object value) {
|
||||||
protected int maxPrecisionStep() {
|
|
||||||
return 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Byte value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (value instanceof Number) {
|
|
||||||
return ((Number) value).byteValue();
|
|
||||||
}
|
|
||||||
if (value instanceof BytesRef) {
|
|
||||||
return ((BytesRef) value).bytes[((BytesRef) value).offset];
|
|
||||||
}
|
|
||||||
return Byte.parseByte(value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BytesRef indexedValueForSearch(Object value) {
|
|
||||||
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
|
||||||
NumericUtils.intToPrefixCoded(parseValue(value), 0, bytesRef); // 0 because of exact match
|
|
||||||
return bytesRef.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte parseValue(Object value) {
|
|
||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
return ((Number) value).byteValue();
|
return ((Number) value).byteValue();
|
||||||
}
|
}
|
||||||
|
@ -184,28 +223,6 @@ public class ByteFieldMapper extends NumberFieldMapper {
|
||||||
return Byte.parseByte(value.toString());
|
return Byte.parseByte(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private int parseValueAsInt(Object value) {
|
|
||||||
return parseValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
|
||||||
byte iValue = Byte.parseByte(value);
|
|
||||||
byte iSim = fuzziness.asByte();
|
|
||||||
return NumericRangeQuery.newIntRange(names.indexName(), precisionStep,
|
|
||||||
iValue - iSim,
|
|
||||||
iValue + iSim,
|
|
||||||
true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
|
||||||
return NumericRangeQuery.newIntRange(names.indexName(), precisionStep,
|
|
||||||
lowerTerm == null ? null : parseValueAsInt(lowerTerm),
|
|
||||||
upperTerm == null ? null : parseValueAsInt(upperTerm),
|
|
||||||
includeLower, includeUpper);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query nullValueFilter() {
|
public Query nullValueFilter() {
|
||||||
if (nullValue == null) {
|
if (nullValue == null) {
|
||||||
|
@ -222,7 +239,7 @@ public class ByteFieldMapper extends NumberFieldMapper {
|
||||||
@Override
|
@Override
|
||||||
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
||||||
byte value;
|
byte value;
|
||||||
float boost = this.boost;
|
float boost = this.fieldType.boost();
|
||||||
if (context.externalValueSet()) {
|
if (context.externalValueSet()) {
|
||||||
Object externalValue = context.externalValue();
|
Object externalValue = context.externalValue();
|
||||||
if (externalValue == null) {
|
if (externalValue == null) {
|
||||||
|
@ -244,7 +261,7 @@ public class ByteFieldMapper extends NumberFieldMapper {
|
||||||
value = ((Number) externalValue).byteValue();
|
value = ((Number) externalValue).byteValue();
|
||||||
}
|
}
|
||||||
if (context.includeInAll(includeInAll, this)) {
|
if (context.includeInAll(includeInAll, this)) {
|
||||||
context.allEntries().addText(names.fullName(), Byte.toString(value), boost);
|
context.allEntries().addText(fieldType.names().fullName(), Byte.toString(value), boost);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
XContentParser parser = context.parser();
|
XContentParser parser = context.parser();
|
||||||
|
@ -255,7 +272,7 @@ public class ByteFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
value = nullValue;
|
value = nullValue;
|
||||||
if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) {
|
if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) {
|
||||||
context.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
context.allEntries().addText(fieldType.names().fullName(), nullValueAsString, boost);
|
||||||
}
|
}
|
||||||
} else if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
|
} else if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
|
@ -284,7 +301,7 @@ public class ByteFieldMapper extends NumberFieldMapper {
|
||||||
} else {
|
} else {
|
||||||
value = (byte) parser.shortValue(coerce.value());
|
value = (byte) parser.shortValue(coerce.value());
|
||||||
if (context.includeInAll(includeInAll, this)) {
|
if (context.includeInAll(includeInAll, this)) {
|
||||||
context.allEntries().addText(names.fullName(), parser.text(), boost);
|
context.allEntries().addText(fieldType.names().fullName(), parser.text(), boost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,7 +310,7 @@ public class ByteFieldMapper extends NumberFieldMapper {
|
||||||
field.setBoost(boost);
|
field.setBoost(boost);
|
||||||
fields.add(field);
|
fields.add(field);
|
||||||
}
|
}
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
addDocValue(context, fields, value);
|
addDocValue(context, fields, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,8 +336,8 @@ public class ByteFieldMapper extends NumberFieldMapper {
|
||||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||||
super.doXContentBody(builder, includeDefaults, params);
|
super.doXContentBody(builder, includeDefaults, params);
|
||||||
|
|
||||||
if (includeDefaults || precisionStep != Defaults.PRECISION_STEP_8_BIT) {
|
if (includeDefaults || fieldType.numericPrecisionStep() != Defaults.PRECISION_STEP_8_BIT) {
|
||||||
builder.field("precision_step", precisionStep);
|
builder.field("precision_step", fieldType.numericPrecisionStep());
|
||||||
}
|
}
|
||||||
if (includeDefaults || nullValue != null) {
|
if (includeDefaults || nullValue != null) {
|
||||||
builder.field("null_value", nullValue);
|
builder.field("null_value", nullValue);
|
||||||
|
@ -332,22 +349,13 @@ public class ByteFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
|
||||||
long minValue = NumericUtils.getMinInt(terms);
|
|
||||||
long maxValue = NumericUtils.getMaxInt(terms);
|
|
||||||
return new FieldStats.Long(
|
|
||||||
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), minValue, maxValue
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CustomByteNumericField extends CustomNumericField {
|
public static class CustomByteNumericField extends CustomNumericField {
|
||||||
|
|
||||||
private final byte number;
|
private final byte number;
|
||||||
|
|
||||||
private final NumberFieldMapper mapper;
|
private final NumberFieldMapper mapper;
|
||||||
|
|
||||||
public CustomByteNumericField(NumberFieldMapper mapper, byte number, FieldType fieldType) {
|
public CustomByteNumericField(NumberFieldMapper mapper, byte number, MappedFieldType fieldType) {
|
||||||
super(mapper, number, fieldType);
|
super(mapper, number, fieldType);
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
this.number = number;
|
this.number = number;
|
||||||
|
|
|
@ -25,7 +25,6 @@ import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.apache.lucene.codecs.PostingsFormat;
|
import org.apache.lucene.codecs.PostingsFormat;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.search.suggest.analyzing.XAnalyzingSuggester;
|
import org.apache.lucene.search.suggest.analyzing.XAnalyzingSuggester;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
import org.elasticsearch.ElasticsearchParseException;
|
||||||
|
@ -39,11 +38,12 @@ import org.elasticsearch.common.xcontent.XContentParser.NumberType;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser.Token;
|
import org.elasticsearch.common.xcontent.XContentParser.Token;
|
||||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperException;
|
import org.elasticsearch.index.mapper.MapperException;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeResult;
|
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
import org.elasticsearch.index.similarity.SimilarityProvider;
|
||||||
import org.elasticsearch.search.suggest.completion.AnalyzingCompletionLookupProvider;
|
import org.elasticsearch.search.suggest.completion.AnalyzingCompletionLookupProvider;
|
||||||
|
@ -72,7 +72,7 @@ public class CompletionFieldMapper extends AbstractFieldMapper {
|
||||||
public static final String CONTENT_TYPE = "completion";
|
public static final String CONTENT_TYPE = "completion";
|
||||||
|
|
||||||
public static class Defaults extends AbstractFieldMapper.Defaults {
|
public static class Defaults extends AbstractFieldMapper.Defaults {
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new CompletionFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setOmitNorms(true);
|
FIELD_TYPE.setOmitNorms(true);
|
||||||
|
@ -114,7 +114,7 @@ public class CompletionFieldMapper extends AbstractFieldMapper {
|
||||||
private SortedMap<String, ContextMapping> contextMapping = ContextMapping.EMPTY_MAPPING;
|
private SortedMap<String, ContextMapping> contextMapping = ContextMapping.EMPTY_MAPPING;
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE));
|
super(name, Defaults.FIELD_TYPE);
|
||||||
builder = this;
|
builder = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,8 @@ public class CompletionFieldMapper extends AbstractFieldMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletionFieldMapper build(Mapper.BuilderContext context) {
|
public CompletionFieldMapper build(Mapper.BuilderContext context) {
|
||||||
return new CompletionFieldMapper(buildNames(context), indexAnalyzer, searchAnalyzer, null, similarity, payloads,
|
setupFieldType(context);
|
||||||
|
return new CompletionFieldMapper(fieldType, null, payloads,
|
||||||
preserveSeparators, preservePositionIncrements, maxInputLength, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo, this.contextMapping);
|
preserveSeparators, preservePositionIncrements, maxInputLength, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo, this.contextMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,6 +220,35 @@ public class CompletionFieldMapper extends AbstractFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class CompletionFieldType extends MappedFieldType {
|
||||||
|
|
||||||
|
public CompletionFieldType() {
|
||||||
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CompletionFieldType(CompletionFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new CompletionFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSortable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final BytesRef EMPTY = new BytesRef();
|
private static final BytesRef EMPTY = new BytesRef();
|
||||||
|
|
||||||
private PostingsFormat postingsFormat;
|
private PostingsFormat postingsFormat;
|
||||||
|
@ -236,9 +266,9 @@ public class CompletionFieldMapper extends AbstractFieldMapper {
|
||||||
*/
|
*/
|
||||||
// Custom postings formats are deprecated but we still accept a postings format here to be able to test backward compatibility
|
// Custom postings formats are deprecated but we still accept a postings format here to be able to test backward compatibility
|
||||||
// with older postings formats such as Elasticsearch090
|
// with older postings formats such as Elasticsearch090
|
||||||
public CompletionFieldMapper(Names names, NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer, PostingsFormat wrappedPostingsFormat, SimilarityProvider similarity, boolean payloads,
|
public CompletionFieldMapper(MappedFieldType fieldType, PostingsFormat wrappedPostingsFormat, boolean payloads,
|
||||||
boolean preserveSeparators, boolean preservePositionIncrements, int maxInputLength, Settings indexSettings, MultiFields multiFields, CopyTo copyTo, SortedMap<String, ContextMapping> contextMappings) {
|
boolean preserveSeparators, boolean preservePositionIncrements, int maxInputLength, Settings indexSettings, MultiFields multiFields, CopyTo copyTo, SortedMap<String, ContextMapping> contextMappings) {
|
||||||
super(names, 1.0f, Defaults.FIELD_TYPE, false, indexAnalyzer, searchAnalyzer, similarity, null, null, indexSettings, multiFields, copyTo);
|
super(fieldType, false, null, indexSettings, multiFields, copyTo);
|
||||||
analyzingSuggestLookupProvider = new AnalyzingCompletionLookupProvider(preserveSeparators, false, preservePositionIncrements, payloads);
|
analyzingSuggestLookupProvider = new AnalyzingCompletionLookupProvider(preserveSeparators, false, preservePositionIncrements, payloads);
|
||||||
if (wrappedPostingsFormat == null) {
|
if (wrappedPostingsFormat == null) {
|
||||||
// delayed until postingsFormat() is called
|
// delayed until postingsFormat() is called
|
||||||
|
@ -424,7 +454,7 @@ public class CompletionFieldMapper extends AbstractFieldMapper {
|
||||||
+ "] at position " + i + " is a reserved character");
|
+ "] at position " + i + " is a reserved character");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new SuggestField(names.indexName(), ctx, input, this.fieldType, payload, analyzingSuggestLookupProvider);
|
return new SuggestField(fieldType.names().indexName(), ctx, input, this.fieldType, payload, analyzingSuggestLookupProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int correctSubStringLen(String input, int len) {
|
public static int correctSubStringLen(String input, int len) {
|
||||||
|
@ -445,7 +475,7 @@ public class CompletionFieldMapper extends AbstractFieldMapper {
|
||||||
private final CompletionTokenStream.ToFiniteStrings toFiniteStrings;
|
private final CompletionTokenStream.ToFiniteStrings toFiniteStrings;
|
||||||
private final ContextMapping.Context ctx;
|
private final ContextMapping.Context ctx;
|
||||||
|
|
||||||
public SuggestField(String name, ContextMapping.Context ctx, String value, FieldType type, BytesRef payload, CompletionTokenStream.ToFiniteStrings toFiniteStrings) {
|
public SuggestField(String name, ContextMapping.Context ctx, String value, MappedFieldType type, BytesRef payload, CompletionTokenStream.ToFiniteStrings toFiniteStrings) {
|
||||||
super(name, value, type);
|
super(name, value, type);
|
||||||
this.payload = payload;
|
this.payload = payload;
|
||||||
this.toFiniteStrings = toFiniteStrings;
|
this.toFiniteStrings = toFiniteStrings;
|
||||||
|
@ -461,12 +491,12 @@ public class CompletionFieldMapper extends AbstractFieldMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject(names().shortName())
|
builder.startObject(fieldType().names().shortName())
|
||||||
.field(Fields.TYPE, CONTENT_TYPE);
|
.field(Fields.TYPE, CONTENT_TYPE);
|
||||||
|
|
||||||
builder.field(Fields.ANALYZER, indexAnalyzer.name());
|
builder.field(Fields.ANALYZER, fieldType.indexAnalyzer().name());
|
||||||
if (indexAnalyzer.name().equals(searchAnalyzer.name()) == false) {
|
if (fieldType.indexAnalyzer().name().equals(fieldType.searchAnalyzer().name()) == false) {
|
||||||
builder.field(Fields.SEARCH_ANALYZER.getPreferredName(), searchAnalyzer.name());
|
builder.field(Fields.SEARCH_ANALYZER.getPreferredName(), fieldType.searchAnalyzer().name());
|
||||||
}
|
}
|
||||||
builder.field(Fields.PAYLOADS, this.payloads);
|
builder.field(Fields.PAYLOADS, this.payloads);
|
||||||
builder.field(Fields.PRESERVE_SEPARATORS.getPreferredName(), this.preserveSeparators);
|
builder.field(Fields.PRESERVE_SEPARATORS.getPreferredName(), this.preserveSeparators);
|
||||||
|
@ -494,18 +524,13 @@ public class CompletionFieldMapper extends AbstractFieldMapper {
|
||||||
return CONTENT_TYPE;
|
return CONTENT_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSortable() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsNullValue() {
|
public boolean supportsNullValue() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,14 +539,6 @@ public class CompletionFieldMapper extends AbstractFieldMapper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isStoringPayloads() {
|
public boolean isStoringPayloads() {
|
||||||
return payloads;
|
return payloads;
|
||||||
}
|
}
|
||||||
|
@ -531,16 +548,16 @@ public class CompletionFieldMapper extends AbstractFieldMapper {
|
||||||
super.merge(mergeWith, mergeResult);
|
super.merge(mergeWith, mergeResult);
|
||||||
CompletionFieldMapper fieldMergeWith = (CompletionFieldMapper) mergeWith;
|
CompletionFieldMapper fieldMergeWith = (CompletionFieldMapper) mergeWith;
|
||||||
if (payloads != fieldMergeWith.payloads) {
|
if (payloads != fieldMergeWith.payloads) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different payload values");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different payload values");
|
||||||
}
|
}
|
||||||
if (preservePositionIncrements != fieldMergeWith.preservePositionIncrements) {
|
if (preservePositionIncrements != fieldMergeWith.preservePositionIncrements) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different 'preserve_position_increments' values");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different 'preserve_position_increments' values");
|
||||||
}
|
}
|
||||||
if (preserveSeparators != fieldMergeWith.preserveSeparators) {
|
if (preserveSeparators != fieldMergeWith.preserveSeparators) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different 'preserve_separators' values");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different 'preserve_separators' values");
|
||||||
}
|
}
|
||||||
if(!ContextMapping.mappingsAreEqual(getContextMapping(), fieldMergeWith.getContextMapping())) {
|
if(!ContextMapping.mappingsAreEqual(getContextMapping(), fieldMergeWith.getContextMapping())) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different 'context_mapping' values");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different 'context_mapping' values");
|
||||||
}
|
}
|
||||||
if (!mergeResult.simulate()) {
|
if (!mergeResult.simulate()) {
|
||||||
this.maxInputLength = fieldMergeWith.maxInputLength;
|
this.maxInputLength = fieldMergeWith.maxInputLength;
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.index.mapper.core;
|
package org.elasticsearch.index.mapper.core;
|
||||||
|
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.index.IndexReader;
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.index.Terms;
|
import org.apache.lucene.index.Terms;
|
||||||
|
@ -44,8 +43,10 @@ import org.elasticsearch.common.unit.Fuzziness;
|
||||||
import org.elasticsearch.common.util.LocaleUtils;
|
import org.elasticsearch.common.util.LocaleUtils;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
import org.elasticsearch.index.analysis.NumericDateAnalyzer;
|
import org.elasticsearch.index.analysis.NumericDateAnalyzer;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -53,7 +54,6 @@ import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.mapper.core.LongFieldMapper.CustomLongNumericField;
|
import org.elasticsearch.index.mapper.core.LongFieldMapper.CustomLongNumericField;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
|
||||||
import org.elasticsearch.search.internal.SearchContext;
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
import org.joda.time.DateTimeZone;
|
import org.joda.time.DateTimeZone;
|
||||||
|
|
||||||
|
@ -75,37 +75,35 @@ public class DateFieldMapper extends NumberFieldMapper {
|
||||||
|
|
||||||
public static class Defaults extends NumberFieldMapper.Defaults {
|
public static class Defaults extends NumberFieldMapper.Defaults {
|
||||||
public static final FormatDateTimeFormatter DATE_TIME_FORMATTER = Joda.forPattern("dateOptionalTime", Locale.ROOT);
|
public static final FormatDateTimeFormatter DATE_TIME_FORMATTER = Joda.forPattern("dateOptionalTime", Locale.ROOT);
|
||||||
|
public static final TimeUnit TIME_UNIT = TimeUnit.MILLISECONDS;
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(NumberFieldMapper.Defaults.FIELD_TYPE);
|
public static final DateFieldType FIELD_TYPE = new DateFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String NULL_VALUE = null;
|
public static final String NULL_VALUE = null;
|
||||||
|
|
||||||
public static final TimeUnit TIME_UNIT = TimeUnit.MILLISECONDS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder extends NumberFieldMapper.Builder<Builder, DateFieldMapper> {
|
public static class Builder extends NumberFieldMapper.Builder<Builder, DateFieldMapper> {
|
||||||
|
|
||||||
protected TimeUnit timeUnit = Defaults.TIME_UNIT;
|
|
||||||
|
|
||||||
protected String nullValue = Defaults.NULL_VALUE;
|
protected String nullValue = Defaults.NULL_VALUE;
|
||||||
|
|
||||||
protected FormatDateTimeFormatter dateTimeFormatter = Defaults.DATE_TIME_FORMATTER;
|
|
||||||
|
|
||||||
private Locale locale;
|
private Locale locale;
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_64_BIT);
|
super(name, Defaults.FIELD_TYPE, Defaults.PRECISION_STEP_64_BIT);
|
||||||
builder = this;
|
builder = this;
|
||||||
// do *NOT* rely on the default locale
|
// do *NOT* rely on the default locale
|
||||||
locale = Locale.ROOT;
|
locale = Locale.ROOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DateFieldType fieldType() {
|
||||||
|
return (DateFieldType)fieldType;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder timeUnit(TimeUnit timeUnit) {
|
public Builder timeUnit(TimeUnit timeUnit) {
|
||||||
this.timeUnit = timeUnit;
|
fieldType().setTimeUnit(timeUnit);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,28 +113,42 @@ public class DateFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder dateTimeFormatter(FormatDateTimeFormatter dateTimeFormatter) {
|
public Builder dateTimeFormatter(FormatDateTimeFormatter dateTimeFormatter) {
|
||||||
this.dateTimeFormatter = dateTimeFormatter;
|
fieldType().setDateTimeFormatter(dateTimeFormatter);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DateFieldMapper build(BuilderContext context) {
|
public DateFieldMapper build(BuilderContext context) {
|
||||||
fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
|
setupFieldType(context);
|
||||||
if (!locale.equals(dateTimeFormatter.locale())) {
|
DateFieldMapper fieldMapper = new DateFieldMapper(fieldType,
|
||||||
dateTimeFormatter = new FormatDateTimeFormatter(dateTimeFormatter.format(), dateTimeFormatter.parser(), dateTimeFormatter.printer(), locale);
|
docValues, nullValue, ignoreMalformed(context), coerce(context),
|
||||||
}
|
fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
||||||
DateFieldMapper fieldMapper = new DateFieldMapper(buildNames(context), dateTimeFormatter,
|
|
||||||
fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue, timeUnit, ignoreMalformed(context), coerce(context),
|
|
||||||
similarity, normsLoading, fieldDataSettings, context.indexSettings(),
|
|
||||||
multiFieldsBuilder.build(this, context), copyTo);
|
|
||||||
fieldMapper.includeInAll(includeInAll);
|
fieldMapper.includeInAll(includeInAll);
|
||||||
return fieldMapper;
|
return fieldMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setupFieldType(BuilderContext context) {
|
||||||
|
FormatDateTimeFormatter dateTimeFormatter = fieldType().dateTimeFormatter;
|
||||||
|
if (!locale.equals(dateTimeFormatter.locale())) {
|
||||||
|
fieldType().setDateTimeFormatter(new FormatDateTimeFormatter(dateTimeFormatter.format(), dateTimeFormatter.parser(), dateTimeFormatter.printer(), locale));
|
||||||
|
}
|
||||||
|
super.setupFieldType(context);
|
||||||
|
}
|
||||||
|
|
||||||
public Builder locale(Locale locale) {
|
public Builder locale(Locale locale) {
|
||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NamedAnalyzer makeNumberAnalyzer(int precisionStep) {
|
||||||
|
return NumericDateAnalyzer.buildNamedAnalyzer(fieldType().dateTimeFormatter, precisionStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int maxPrecisionStep() {
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TypeParser implements Mapper.TypeParser {
|
public static class TypeParser implements Mapper.TypeParser {
|
||||||
|
@ -169,37 +181,222 @@ public class DateFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected FormatDateTimeFormatter dateTimeFormatter;
|
public static class DateFieldType extends NumberFieldType {
|
||||||
|
|
||||||
private final DateMathParser dateMathParser;
|
final class LateParsingQuery extends Query {
|
||||||
|
|
||||||
|
final Object lowerTerm;
|
||||||
|
final Object upperTerm;
|
||||||
|
final boolean includeLower;
|
||||||
|
final boolean includeUpper;
|
||||||
|
final DateTimeZone timeZone;
|
||||||
|
final DateMathParser forcedDateParser;
|
||||||
|
|
||||||
|
public LateParsingQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, DateTimeZone timeZone, DateMathParser forcedDateParser) {
|
||||||
|
this.lowerTerm = lowerTerm;
|
||||||
|
this.upperTerm = upperTerm;
|
||||||
|
this.includeLower = includeLower;
|
||||||
|
this.includeUpper = includeUpper;
|
||||||
|
this.timeZone = timeZone;
|
||||||
|
this.forcedDateParser = forcedDateParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query rewrite(IndexReader reader) throws IOException {
|
||||||
|
Query query = innerRangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, timeZone, forcedDateParser);
|
||||||
|
return query.rewrite(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(String s) {
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
return sb.append(names().indexName()).append(':')
|
||||||
|
.append(includeLower ? '[' : '{')
|
||||||
|
.append((lowerTerm == null) ? "*" : lowerTerm.toString())
|
||||||
|
.append(" TO ")
|
||||||
|
.append((upperTerm == null) ? "*" : upperTerm.toString())
|
||||||
|
.append(includeUpper ? ']' : '}')
|
||||||
|
.append(ToStringUtils.boost(getBoost()))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected FormatDateTimeFormatter dateTimeFormatter = Defaults.DATE_TIME_FORMATTER;
|
||||||
|
protected TimeUnit timeUnit = Defaults.TIME_UNIT;
|
||||||
|
protected DateMathParser dateMathParser = new DateMathParser(dateTimeFormatter, timeUnit);
|
||||||
|
|
||||||
|
public DateFieldType() {}
|
||||||
|
|
||||||
|
protected DateFieldType(DateFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
this.dateTimeFormatter = ref.dateTimeFormatter;
|
||||||
|
this.timeUnit = ref.timeUnit;
|
||||||
|
this.dateMathParser = ref.dateMathParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateFieldType clone() {
|
||||||
|
return new DateFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FormatDateTimeFormatter dateTimeFormatter() {
|
||||||
|
return dateTimeFormatter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDateTimeFormatter(FormatDateTimeFormatter dateTimeFormatter) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.dateTimeFormatter = dateTimeFormatter;
|
||||||
|
this.dateMathParser = new DateMathParser(dateTimeFormatter, timeUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeUnit timeUnit() {
|
||||||
|
return timeUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeUnit(TimeUnit timeUnit) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.timeUnit = timeUnit;
|
||||||
|
this.dateMathParser = new DateMathParser(dateTimeFormatter, timeUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected DateMathParser dateMathParser() {
|
||||||
|
return dateMathParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected long parseStringValue(String value) {
|
||||||
|
try {
|
||||||
|
return dateTimeFormatter().parser().parseMillis(value);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
try {
|
||||||
|
return timeUnit().toMillis(Long.parseLong(value));
|
||||||
|
} catch (NumberFormatException e1) {
|
||||||
|
throw new MapperParsingException("failed to parse date field [" + value + "], tried both date format [" + dateTimeFormatter().format() + "], and timestamp number with locale [" + dateTimeFormatter().locale() + "]", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).longValue();
|
||||||
|
}
|
||||||
|
if (value instanceof BytesRef) {
|
||||||
|
return Numbers.bytesToLong((BytesRef) value);
|
||||||
|
}
|
||||||
|
return parseStringValue(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BytesRef indexedValueForSearch(Object value) {
|
||||||
|
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
||||||
|
NumericUtils.longToPrefixCoded(parseValue(value), 0, bytesRef); // 0 because of exact match
|
||||||
|
return bytesRef.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object valueForSearch(Object value) {
|
||||||
|
if (value instanceof String) {
|
||||||
|
// assume its the string that was indexed, just return it... (for example, with get)
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
Long val = value(value);
|
||||||
|
if (val == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return dateTimeFormatter().printer().print(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
||||||
|
return rangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, null, null, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
||||||
|
long iValue = dateMathParser().parse(value, now());
|
||||||
|
long iSim;
|
||||||
|
try {
|
||||||
|
iSim = fuzziness.asTimeValue().millis();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// not a time format
|
||||||
|
iSim = fuzziness.asLong();
|
||||||
|
}
|
||||||
|
return NumericRangeQuery.newLongRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
iValue - iSim,
|
||||||
|
iValue + iSim,
|
||||||
|
true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
||||||
|
long minValue = NumericUtils.getMinLong(terms);
|
||||||
|
long maxValue = NumericUtils.getMaxLong(terms);
|
||||||
|
return new FieldStats.Date(
|
||||||
|
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), minValue, maxValue, dateTimeFormatter()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable DateTimeZone timeZone, @Nullable DateMathParser forcedDateParser, @Nullable QueryParseContext context) {
|
||||||
|
// If the current search context is null we're parsing percolator query or a index alias filter.
|
||||||
|
if (SearchContext.current() == null) {
|
||||||
|
return new LateParsingQuery(lowerTerm, upperTerm, includeLower, includeUpper, timeZone, forcedDateParser);
|
||||||
|
} else {
|
||||||
|
return innerRangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, timeZone, forcedDateParser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Query innerRangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable DateTimeZone timeZone, @Nullable DateMathParser forcedDateParser) {
|
||||||
|
return NumericRangeQuery.newLongRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
lowerTerm == null ? null : parseToMilliseconds(lowerTerm, !includeLower, timeZone, forcedDateParser == null ? dateMathParser : forcedDateParser),
|
||||||
|
upperTerm == null ? null : parseToMilliseconds(upperTerm, includeUpper, timeZone, forcedDateParser == null ? dateMathParser : forcedDateParser),
|
||||||
|
includeLower, includeUpper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long parseToMilliseconds(Object value, boolean inclusive, @Nullable DateTimeZone zone, @Nullable DateMathParser forcedDateParser) {
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).longValue();
|
||||||
|
}
|
||||||
|
DateMathParser dateParser = dateMathParser();
|
||||||
|
if (forcedDateParser != null) {
|
||||||
|
dateParser = forcedDateParser;
|
||||||
|
}
|
||||||
|
String strValue;
|
||||||
|
if (value instanceof BytesRef) {
|
||||||
|
strValue = ((BytesRef) value).utf8ToString();
|
||||||
|
} else {
|
||||||
|
strValue = value.toString();
|
||||||
|
}
|
||||||
|
return dateParser.parse(strValue, now(), inclusive, zone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String nullValue;
|
private String nullValue;
|
||||||
|
|
||||||
protected final TimeUnit timeUnit;
|
protected DateFieldMapper(MappedFieldType fieldType, Boolean docValues, String nullValue, Explicit<Boolean> ignoreMalformed,Explicit<Boolean> coerce,
|
||||||
|
@Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||||
protected DateFieldMapper(Names names, FormatDateTimeFormatter dateTimeFormatter, int precisionStep, float boost, FieldType fieldType, Boolean docValues,
|
super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||||
String nullValue, TimeUnit timeUnit, Explicit<Boolean> ignoreMalformed,Explicit<Boolean> coerce,
|
|
||||||
SimilarityProvider similarity,
|
|
||||||
Loading normsLoading, @Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
|
||||||
super(names, precisionStep, boost, fieldType, docValues, ignoreMalformed, coerce, NumericDateAnalyzer.buildNamedAnalyzer(dateTimeFormatter, precisionStep),
|
|
||||||
NumericDateAnalyzer.buildNamedAnalyzer(dateTimeFormatter, Integer.MAX_VALUE),
|
|
||||||
similarity, normsLoading, fieldDataSettings, indexSettings, multiFields, copyTo);
|
|
||||||
this.dateTimeFormatter = dateTimeFormatter;
|
|
||||||
this.nullValue = nullValue;
|
this.nullValue = nullValue;
|
||||||
this.timeUnit = timeUnit;
|
|
||||||
this.dateMathParser = new DateMathParser(dateTimeFormatter, timeUnit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public FormatDateTimeFormatter dateTimeFormatter() {
|
|
||||||
return dateTimeFormatter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DateMathParser dateMathParser() {
|
|
||||||
return dateMathParser;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public DateFieldType fieldType() {
|
||||||
|
return (DateFieldType)fieldType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,63 +405,6 @@ public class DateFieldMapper extends NumberFieldMapper {
|
||||||
return new FieldDataType("long");
|
return new FieldDataType("long");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int maxPrecisionStep() {
|
|
||||||
return 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (value instanceof Number) {
|
|
||||||
return ((Number) value).longValue();
|
|
||||||
}
|
|
||||||
if (value instanceof BytesRef) {
|
|
||||||
return Numbers.bytesToLong((BytesRef) value);
|
|
||||||
}
|
|
||||||
return parseStringValue(value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Dates should return as a string. */
|
|
||||||
@Override
|
|
||||||
public Object valueForSearch(Object value) {
|
|
||||||
if (value instanceof String) {
|
|
||||||
// assume its the string that was indexed, just return it... (for example, with get)
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
Long val = value(value);
|
|
||||||
if (val == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return dateTimeFormatter.printer().print(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BytesRef indexedValueForSearch(Object value) {
|
|
||||||
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
|
||||||
NumericUtils.longToPrefixCoded(parseValue(value), 0, bytesRef); // 0 because of exact match
|
|
||||||
return bytesRef.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Callable<Long> now() {
|
private static Callable<Long> now() {
|
||||||
return new Callable<Long>() {
|
return new Callable<Long>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -277,62 +417,6 @@ public class DateFieldMapper extends NumberFieldMapper {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
|
||||||
long iValue = dateMathParser.parse(value, now());
|
|
||||||
long iSim;
|
|
||||||
try {
|
|
||||||
iSim = fuzziness.asTimeValue().millis();
|
|
||||||
} catch (Exception e) {
|
|
||||||
// not a time format
|
|
||||||
iSim = fuzziness.asLong();
|
|
||||||
}
|
|
||||||
return NumericRangeQuery.newLongRange(names.indexName(), precisionStep,
|
|
||||||
iValue - iSim,
|
|
||||||
iValue + iSim,
|
|
||||||
true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long parseToMilliseconds(Object value) {
|
|
||||||
return parseToMilliseconds(value, false, null, dateMathParser);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long parseToMilliseconds(Object value, boolean inclusive, @Nullable DateTimeZone zone, @Nullable DateMathParser forcedDateParser) {
|
|
||||||
if (value instanceof Number) {
|
|
||||||
return ((Number) value).longValue();
|
|
||||||
}
|
|
||||||
return parseToMilliseconds(convertToString(value), inclusive, zone, forcedDateParser);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long parseToMilliseconds(String value, boolean inclusive, @Nullable DateTimeZone zone, @Nullable DateMathParser forcedDateParser) {
|
|
||||||
DateMathParser dateParser = dateMathParser;
|
|
||||||
if (forcedDateParser != null) {
|
|
||||||
dateParser = forcedDateParser;
|
|
||||||
}
|
|
||||||
return dateParser.parse(value, now(), inclusive, zone);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
|
||||||
return rangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, null, null, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable DateTimeZone timeZone, @Nullable DateMathParser forcedDateParser, @Nullable QueryParseContext context) {
|
|
||||||
// If the current search context is null we're parsing percolator query or a index alias filter.
|
|
||||||
if (SearchContext.current() == null) {
|
|
||||||
return new LateParsingQuery(lowerTerm, upperTerm, includeLower, includeUpper, timeZone, forcedDateParser);
|
|
||||||
} else {
|
|
||||||
return innerRangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, timeZone, forcedDateParser);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Query innerRangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable DateTimeZone timeZone, @Nullable DateMathParser forcedDateParser) {
|
|
||||||
return NumericRangeQuery.newLongRange(names.indexName(), precisionStep,
|
|
||||||
lowerTerm == null ? null : parseToMilliseconds(lowerTerm, !includeLower, timeZone, forcedDateParser == null ? dateMathParser : forcedDateParser),
|
|
||||||
upperTerm == null ? null : parseToMilliseconds(upperTerm, includeUpper, timeZone, forcedDateParser == null ? dateMathParser : forcedDateParser),
|
|
||||||
includeLower, includeUpper);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query nullValueFilter() {
|
public Query nullValueFilter() {
|
||||||
if (nullValue == null) {
|
if (nullValue == null) {
|
||||||
|
@ -351,7 +435,7 @@ public class DateFieldMapper extends NumberFieldMapper {
|
||||||
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
||||||
String dateAsString = null;
|
String dateAsString = null;
|
||||||
Long value = null;
|
Long value = null;
|
||||||
float boost = this.boost;
|
float boost = this.fieldType.boost();
|
||||||
if (context.externalValueSet()) {
|
if (context.externalValueSet()) {
|
||||||
Object externalValue = context.externalValue();
|
Object externalValue = context.externalValue();
|
||||||
if (externalValue instanceof Number) {
|
if (externalValue instanceof Number) {
|
||||||
|
@ -398,20 +482,20 @@ public class DateFieldMapper extends NumberFieldMapper {
|
||||||
if (dateAsString != null) {
|
if (dateAsString != null) {
|
||||||
assert value == null;
|
assert value == null;
|
||||||
if (context.includeInAll(includeInAll, this)) {
|
if (context.includeInAll(includeInAll, this)) {
|
||||||
context.allEntries().addText(names.fullName(), dateAsString, boost);
|
context.allEntries().addText(fieldType.names().fullName(), dateAsString, boost);
|
||||||
}
|
}
|
||||||
value = parseStringValue(dateAsString);
|
value = fieldType().parseStringValue(dateAsString);
|
||||||
} else if (value != null) {
|
} else if (value != null) {
|
||||||
value = timeUnit.toMillis(value);
|
value = ((DateFieldType)fieldType).timeUnit().toMillis(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
||||||
CustomLongNumericField field = new CustomLongNumericField(this, value, fieldType);
|
CustomLongNumericField field = new CustomLongNumericField(this, value, (NumberFieldType)fieldType);
|
||||||
field.setBoost(boost);
|
field.setBoost(boost);
|
||||||
fields.add(field);
|
fields.add(field);
|
||||||
}
|
}
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
addDocValue(context, fields, value);
|
addDocValue(context, fields, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -430,7 +514,9 @@ public class DateFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
if (!mergeResult.simulate()) {
|
if (!mergeResult.simulate()) {
|
||||||
this.nullValue = ((DateFieldMapper) mergeWith).nullValue;
|
this.nullValue = ((DateFieldMapper) mergeWith).nullValue;
|
||||||
this.dateTimeFormatter = ((DateFieldMapper) mergeWith).dateTimeFormatter;
|
this.fieldType = this.fieldType.clone();
|
||||||
|
fieldType().setDateTimeFormatter(((DateFieldMapper) mergeWith).fieldType().dateTimeFormatter());
|
||||||
|
this.fieldType.freeze();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,10 +524,10 @@ public class DateFieldMapper extends NumberFieldMapper {
|
||||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||||
super.doXContentBody(builder, includeDefaults, params);
|
super.doXContentBody(builder, includeDefaults, params);
|
||||||
|
|
||||||
if (includeDefaults || precisionStep != Defaults.PRECISION_STEP_64_BIT) {
|
if (includeDefaults || fieldType.numericPrecisionStep() != Defaults.PRECISION_STEP_64_BIT) {
|
||||||
builder.field("precision_step", precisionStep);
|
builder.field("precision_step", fieldType.numericPrecisionStep());
|
||||||
}
|
}
|
||||||
builder.field("format", dateTimeFormatter.format());
|
builder.field("format", fieldType().dateTimeFormatter().format());
|
||||||
if (includeDefaults || nullValue != null) {
|
if (includeDefaults || nullValue != null) {
|
||||||
builder.field("null_value", nullValue);
|
builder.field("null_value", nullValue);
|
||||||
}
|
}
|
||||||
|
@ -451,77 +537,18 @@ public class DateFieldMapper extends NumberFieldMapper {
|
||||||
builder.field("include_in_all", false);
|
builder.field("include_in_all", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (includeDefaults || timeUnit != Defaults.TIME_UNIT) {
|
if (includeDefaults || fieldType().timeUnit() != Defaults.TIME_UNIT) {
|
||||||
builder.field("numeric_resolution", timeUnit.name().toLowerCase(Locale.ROOT));
|
builder.field("numeric_resolution", fieldType().timeUnit().name().toLowerCase(Locale.ROOT));
|
||||||
}
|
}
|
||||||
// only serialize locale if needed, ROOT is the default, so no need to serialize that case as well...
|
// only serialize locale if needed, ROOT is the default, so no need to serialize that case as well...
|
||||||
if (dateTimeFormatter.locale() != null && dateTimeFormatter.locale() != Locale.ROOT) {
|
if (fieldType().dateTimeFormatter().locale() != null && fieldType().dateTimeFormatter().locale() != Locale.ROOT) {
|
||||||
builder.field("locale", dateTimeFormatter.locale());
|
builder.field("locale", fieldType().dateTimeFormatter().locale());
|
||||||
} else if (includeDefaults) {
|
} else if (includeDefaults) {
|
||||||
if (dateTimeFormatter.locale() == null) {
|
if (fieldType().dateTimeFormatter().locale() == null) {
|
||||||
builder.field("locale", Locale.ROOT);
|
builder.field("locale", Locale.ROOT);
|
||||||
} else {
|
} else {
|
||||||
builder.field("locale", dateTimeFormatter.locale());
|
builder.field("locale", fieldType().dateTimeFormatter().locale());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
|
||||||
long minValue = NumericUtils.getMinLong(terms);
|
|
||||||
long maxValue = NumericUtils.getMaxLong(terms);
|
|
||||||
return new FieldStats.Date(
|
|
||||||
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), minValue, maxValue, dateTimeFormatter
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private long parseStringValue(String value) {
|
|
||||||
try {
|
|
||||||
return dateTimeFormatter.parser().parseMillis(value);
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
try {
|
|
||||||
return timeUnit.toMillis(Long.parseLong(value));
|
|
||||||
} catch (NumberFormatException e1) {
|
|
||||||
throw new MapperParsingException("failed to parse date field [" + value + "], tried both date format [" + dateTimeFormatter.format() + "], and timestamp number with locale [" + dateTimeFormatter.locale() + "]", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class LateParsingQuery extends Query {
|
|
||||||
|
|
||||||
final Object lowerTerm;
|
|
||||||
final Object upperTerm;
|
|
||||||
final boolean includeLower;
|
|
||||||
final boolean includeUpper;
|
|
||||||
final DateTimeZone timeZone;
|
|
||||||
final DateMathParser forcedDateParser;
|
|
||||||
|
|
||||||
public LateParsingQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, DateTimeZone timeZone, DateMathParser forcedDateParser) {
|
|
||||||
this.lowerTerm = lowerTerm;
|
|
||||||
this.upperTerm = upperTerm;
|
|
||||||
this.includeLower = includeLower;
|
|
||||||
this.includeUpper = includeUpper;
|
|
||||||
this.timeZone = timeZone;
|
|
||||||
this.forcedDateParser = forcedDateParser;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query rewrite(IndexReader reader) throws IOException {
|
|
||||||
Query query = innerRangeQuery(lowerTerm, upperTerm, includeLower, includeUpper, timeZone, forcedDateParser);
|
|
||||||
return query.rewrite(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString(String s) {
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
return sb.append(names.indexName()).append(':')
|
|
||||||
.append(includeLower ? '[' : '{')
|
|
||||||
.append((lowerTerm == null) ? "*" : lowerTerm.toString())
|
|
||||||
.append(" TO ")
|
|
||||||
.append((upperTerm == null) ? "*" : upperTerm.toString())
|
|
||||||
.append(includeUpper ? ']' : '}')
|
|
||||||
.append(ToStringUtils.boost(getBoost()))
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,10 @@
|
||||||
package org.elasticsearch.index.mapper.core;
|
package org.elasticsearch.index.mapper.core;
|
||||||
|
|
||||||
import com.carrotsearch.hppc.DoubleArrayList;
|
import com.carrotsearch.hppc.DoubleArrayList;
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
import org.apache.lucene.document.FieldType;
|
||||||
import org.apache.lucene.index.DocValuesType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.index.Terms;
|
import org.apache.lucene.index.Terms;
|
||||||
import org.apache.lucene.search.ConstantScoreQuery;
|
import org.apache.lucene.search.ConstantScoreQuery;
|
||||||
|
@ -44,21 +42,23 @@ import org.elasticsearch.common.util.ByteUtils;
|
||||||
import org.elasticsearch.common.util.CollectionUtils;
|
import org.elasticsearch.common.util.CollectionUtils;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
import org.elasticsearch.index.analysis.NumericDoubleAnalyzer;
|
import org.elasticsearch.index.analysis.NumericDoubleAnalyzer;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
import org.elasticsearch.index.mapper.MergeResult;
|
import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.apache.lucene.util.NumericUtils.doubleToSortableLong;
|
||||||
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeDoubleValue;
|
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeDoubleValue;
|
||||||
import static org.elasticsearch.index.mapper.MapperBuilders.doubleField;
|
import static org.elasticsearch.index.mapper.MapperBuilders.doubleField;
|
||||||
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
|
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
|
||||||
|
@ -71,7 +71,7 @@ public class DoubleFieldMapper extends NumberFieldMapper {
|
||||||
public static final String CONTENT_TYPE = "double";
|
public static final String CONTENT_TYPE = "double";
|
||||||
|
|
||||||
public static class Defaults extends NumberFieldMapper.Defaults {
|
public static class Defaults extends NumberFieldMapper.Defaults {
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(NumberFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new DoubleFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
|
@ -85,7 +85,7 @@ public class DoubleFieldMapper extends NumberFieldMapper {
|
||||||
protected Double nullValue = Defaults.NULL_VALUE;
|
protected Double nullValue = Defaults.NULL_VALUE;
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_64_BIT);
|
super(name, Defaults.FIELD_TYPE, Defaults.PRECISION_STEP_64_BIT);
|
||||||
builder = this;
|
builder = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,13 +96,22 @@ public class DoubleFieldMapper extends NumberFieldMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DoubleFieldMapper build(BuilderContext context) {
|
public DoubleFieldMapper build(BuilderContext context) {
|
||||||
fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
|
setupFieldType(context);
|
||||||
DoubleFieldMapper fieldMapper = new DoubleFieldMapper(buildNames(context),
|
DoubleFieldMapper fieldMapper = new DoubleFieldMapper(fieldType, docValues, nullValue, ignoreMalformed(context), coerce(context),
|
||||||
fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue, ignoreMalformed(context), coerce(context),
|
fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
||||||
similarity, normsLoading, fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
|
||||||
fieldMapper.includeInAll(includeInAll);
|
fieldMapper.includeInAll(includeInAll);
|
||||||
return fieldMapper;
|
return fieldMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NamedAnalyzer makeNumberAnalyzer(int precisionStep) {
|
||||||
|
return NumericDoubleAnalyzer.buildNamedAnalyzer(precisionStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int maxPrecisionStep() {
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TypeParser implements Mapper.TypeParser {
|
public static class TypeParser implements Mapper.TypeParser {
|
||||||
|
@ -126,24 +135,82 @@ public class DoubleFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class DoubleFieldType extends NumberFieldType {
|
||||||
|
|
||||||
|
public DoubleFieldType() {}
|
||||||
|
|
||||||
|
protected DoubleFieldType(DoubleFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NumberFieldType clone() {
|
||||||
|
return new DoubleFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).doubleValue();
|
||||||
|
}
|
||||||
|
if (value instanceof BytesRef) {
|
||||||
|
return Numbers.bytesToDouble((BytesRef) value);
|
||||||
|
}
|
||||||
|
return Double.parseDouble(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BytesRef indexedValueForSearch(Object value) {
|
||||||
|
long longValue = NumericUtils.doubleToSortableLong(parseDoubleValue(value));
|
||||||
|
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
||||||
|
NumericUtils.longToPrefixCoded(longValue, 0, bytesRef); // 0 because of exact match
|
||||||
|
return bytesRef.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
||||||
|
return NumericRangeQuery.newDoubleRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
lowerTerm == null ? null : parseDoubleValue(lowerTerm),
|
||||||
|
upperTerm == null ? null : parseDoubleValue(upperTerm),
|
||||||
|
includeLower, includeUpper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
||||||
|
double iValue = Double.parseDouble(value);
|
||||||
|
double iSim = fuzziness.asDouble();
|
||||||
|
return NumericRangeQuery.newDoubleRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
iValue - iSim,
|
||||||
|
iValue + iSim,
|
||||||
|
true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
||||||
|
double minValue = NumericUtils.sortableLongToDouble(NumericUtils.getMinLong(terms));
|
||||||
|
double maxValue = NumericUtils.sortableLongToDouble(NumericUtils.getMaxLong(terms));
|
||||||
|
return new FieldStats.Double(
|
||||||
|
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), minValue, maxValue
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Double nullValue;
|
private Double nullValue;
|
||||||
|
|
||||||
private String nullValueAsString;
|
private String nullValueAsString;
|
||||||
|
|
||||||
protected DoubleFieldMapper(Names names, int precisionStep, float boost, FieldType fieldType, Boolean docValues,
|
protected DoubleFieldMapper(MappedFieldType fieldType, Boolean docValues, Double nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
||||||
Double nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
@Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||||
SimilarityProvider similarity, Loading normsLoading, @Nullable Settings fieldDataSettings,
|
super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||||
Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
|
||||||
super(names, precisionStep, boost, fieldType, docValues, ignoreMalformed, coerce,
|
|
||||||
NumericDoubleAnalyzer.buildNamedAnalyzer(precisionStep), NumericDoubleAnalyzer.buildNamedAnalyzer(Integer.MAX_VALUE),
|
|
||||||
similarity, normsLoading, fieldDataSettings, indexSettings, multiFields, copyTo);
|
|
||||||
this.nullValue = nullValue;
|
this.nullValue = nullValue;
|
||||||
this.nullValueAsString = nullValue == null ? null : nullValue.toString();
|
this.nullValueAsString = nullValue == null ? null : nullValue.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,53 +219,8 @@ public class DoubleFieldMapper extends NumberFieldMapper {
|
||||||
return new FieldDataType("double");
|
return new FieldDataType("double");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int maxPrecisionStep() {
|
|
||||||
return 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Double value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (value instanceof Number) {
|
|
||||||
return ((Number) value).doubleValue();
|
|
||||||
}
|
|
||||||
if (value instanceof BytesRef) {
|
|
||||||
return Numbers.bytesToDouble((BytesRef) value);
|
|
||||||
}
|
|
||||||
return Double.parseDouble(value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BytesRef indexedValueForSearch(Object value) {
|
|
||||||
long longValue = NumericUtils.doubleToSortableLong(parseDoubleValue(value));
|
|
||||||
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
|
||||||
NumericUtils.longToPrefixCoded(longValue, 0, bytesRef); // 0 because of exact match
|
|
||||||
return bytesRef.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
|
||||||
double iValue = Double.parseDouble(value);
|
|
||||||
double iSim = fuzziness.asDouble();
|
|
||||||
return NumericRangeQuery.newDoubleRange(names.indexName(), precisionStep,
|
|
||||||
iValue - iSim,
|
|
||||||
iValue + iSim,
|
|
||||||
true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
|
||||||
return NumericRangeQuery.newDoubleRange(names.indexName(), precisionStep,
|
|
||||||
lowerTerm == null ? null : parseDoubleValue(lowerTerm),
|
|
||||||
upperTerm == null ? null : parseDoubleValue(upperTerm),
|
|
||||||
includeLower, includeUpper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Query rangeFilter(Double lowerTerm, Double upperTerm, boolean includeLower, boolean includeUpper) {
|
public Query rangeFilter(Double lowerTerm, Double upperTerm, boolean includeLower, boolean includeUpper) {
|
||||||
return NumericRangeQuery.newDoubleRange(names.indexName(), precisionStep, lowerTerm, upperTerm, includeLower, includeUpper);
|
return NumericRangeQuery.newDoubleRange(fieldType.names().indexName(), fieldType.numericPrecisionStep(), lowerTerm, upperTerm, includeLower, includeUpper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -217,7 +239,7 @@ public class DoubleFieldMapper extends NumberFieldMapper {
|
||||||
@Override
|
@Override
|
||||||
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
||||||
double value;
|
double value;
|
||||||
float boost = this.boost;
|
float boost = this.fieldType.boost();
|
||||||
if (context.externalValueSet()) {
|
if (context.externalValueSet()) {
|
||||||
Object externalValue = context.externalValue();
|
Object externalValue = context.externalValue();
|
||||||
if (externalValue == null) {
|
if (externalValue == null) {
|
||||||
|
@ -239,7 +261,7 @@ public class DoubleFieldMapper extends NumberFieldMapper {
|
||||||
value = ((Number) externalValue).doubleValue();
|
value = ((Number) externalValue).doubleValue();
|
||||||
}
|
}
|
||||||
if (context.includeInAll(includeInAll, this)) {
|
if (context.includeInAll(includeInAll, this)) {
|
||||||
context.allEntries().addText(names.fullName(), Double.toString(value), boost);
|
context.allEntries().addText(fieldType.names().fullName(), Double.toString(value), boost);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
XContentParser parser = context.parser();
|
XContentParser parser = context.parser();
|
||||||
|
@ -250,7 +272,7 @@ public class DoubleFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
value = nullValue;
|
value = nullValue;
|
||||||
if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) {
|
if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) {
|
||||||
context.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
context.allEntries().addText(fieldType.names().fullName(), nullValueAsString, boost);
|
||||||
}
|
}
|
||||||
} else if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
|
} else if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
|
@ -279,26 +301,26 @@ public class DoubleFieldMapper extends NumberFieldMapper {
|
||||||
} else {
|
} else {
|
||||||
value = parser.doubleValue(coerce.value());
|
value = parser.doubleValue(coerce.value());
|
||||||
if (context.includeInAll(includeInAll, this)) {
|
if (context.includeInAll(includeInAll, this)) {
|
||||||
context.allEntries().addText(names.fullName(), parser.text(), boost);
|
context.allEntries().addText(fieldType.names().fullName(), parser.text(), boost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
||||||
CustomDoubleNumericField field = new CustomDoubleNumericField(this, value, fieldType);
|
CustomDoubleNumericField field = new CustomDoubleNumericField(this, value, (NumberFieldType)fieldType);
|
||||||
field.setBoost(boost);
|
field.setBoost(boost);
|
||||||
fields.add(field);
|
fields.add(field);
|
||||||
}
|
}
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
if (useSortedNumericDocValues) {
|
if (useSortedNumericDocValues) {
|
||||||
addDocValue(context, fields, NumericUtils.doubleToSortableLong(value));
|
addDocValue(context, fields, doubleToSortableLong(value));
|
||||||
} else {
|
} else {
|
||||||
CustomDoubleNumericDocValuesField field = (CustomDoubleNumericDocValuesField) context.doc().getByKey(names().indexName());
|
CustomDoubleNumericDocValuesField field = (CustomDoubleNumericDocValuesField) context.doc().getByKey(fieldType().names().indexName());
|
||||||
if (field != null) {
|
if (field != null) {
|
||||||
field.add(value);
|
field.add(value);
|
||||||
} else {
|
} else {
|
||||||
field = new CustomDoubleNumericDocValuesField(names().indexName(), value);
|
field = new CustomDoubleNumericDocValuesField(fieldType().names().indexName(), value);
|
||||||
context.doc().addWithKey(names().indexName(), field);
|
context.doc().addWithKey(fieldType().names().indexName(), field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -325,8 +347,8 @@ public class DoubleFieldMapper extends NumberFieldMapper {
|
||||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||||
super.doXContentBody(builder, includeDefaults, params);
|
super.doXContentBody(builder, includeDefaults, params);
|
||||||
|
|
||||||
if (includeDefaults || precisionStep != Defaults.PRECISION_STEP_64_BIT) {
|
if (includeDefaults || fieldType.numericPrecisionStep() != Defaults.PRECISION_STEP_64_BIT) {
|
||||||
builder.field("precision_step", precisionStep);
|
builder.field("precision_step", fieldType.numericPrecisionStep());
|
||||||
}
|
}
|
||||||
if (includeDefaults || nullValue != null) {
|
if (includeDefaults || nullValue != null) {
|
||||||
builder.field("null_value", nullValue);
|
builder.field("null_value", nullValue);
|
||||||
|
@ -339,22 +361,13 @@ public class DoubleFieldMapper extends NumberFieldMapper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
|
||||||
double minValue = NumericUtils.sortableLongToDouble(NumericUtils.getMinLong(terms));
|
|
||||||
double maxValue = NumericUtils.sortableLongToDouble(NumericUtils.getMaxLong(terms));
|
|
||||||
return new FieldStats.Double(
|
|
||||||
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), minValue, maxValue
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CustomDoubleNumericField extends CustomNumericField {
|
public static class CustomDoubleNumericField extends CustomNumericField {
|
||||||
|
|
||||||
private final double number;
|
private final double number;
|
||||||
|
|
||||||
private final NumberFieldMapper mapper;
|
private final NumberFieldMapper mapper;
|
||||||
|
|
||||||
public CustomDoubleNumericField(NumberFieldMapper mapper, double number, FieldType fieldType) {
|
public CustomDoubleNumericField(NumberFieldMapper mapper, double number, NumberFieldType fieldType) {
|
||||||
super(mapper, number, fieldType);
|
super(mapper, number, fieldType);
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
this.number = number;
|
this.number = number;
|
||||||
|
@ -376,12 +389,6 @@ public class DoubleFieldMapper extends NumberFieldMapper {
|
||||||
|
|
||||||
public static class CustomDoubleNumericDocValuesField extends CustomNumericDocValuesField {
|
public static class CustomDoubleNumericDocValuesField extends CustomNumericDocValuesField {
|
||||||
|
|
||||||
public static final FieldType TYPE = new FieldType();
|
|
||||||
static {
|
|
||||||
TYPE.setDocValuesType(DocValuesType.BINARY);
|
|
||||||
TYPE.freeze();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final DoubleArrayList values;
|
private final DoubleArrayList values;
|
||||||
|
|
||||||
public CustomDoubleNumericDocValuesField(String name, double value) {
|
public CustomDoubleNumericDocValuesField(String name, double value) {
|
||||||
|
|
|
@ -20,11 +20,9 @@
|
||||||
package org.elasticsearch.index.mapper.core;
|
package org.elasticsearch.index.mapper.core;
|
||||||
|
|
||||||
import com.carrotsearch.hppc.FloatArrayList;
|
import com.carrotsearch.hppc.FloatArrayList;
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.DocValuesType;
|
import org.apache.lucene.index.DocValuesType;
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.index.Terms;
|
import org.apache.lucene.index.Terms;
|
||||||
|
@ -45,21 +43,23 @@ import org.elasticsearch.common.util.ByteUtils;
|
||||||
import org.elasticsearch.common.util.CollectionUtils;
|
import org.elasticsearch.common.util.CollectionUtils;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
import org.elasticsearch.index.analysis.NumericFloatAnalyzer;
|
import org.elasticsearch.index.analysis.NumericFloatAnalyzer;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
import org.elasticsearch.index.mapper.MergeResult;
|
import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.apache.lucene.util.NumericUtils.floatToSortableInt;
|
||||||
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeFloatValue;
|
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeFloatValue;
|
||||||
import static org.elasticsearch.index.mapper.MapperBuilders.floatField;
|
import static org.elasticsearch.index.mapper.MapperBuilders.floatField;
|
||||||
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
|
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
|
||||||
|
@ -72,7 +72,7 @@ public class FloatFieldMapper extends NumberFieldMapper {
|
||||||
public static final String CONTENT_TYPE = "float";
|
public static final String CONTENT_TYPE = "float";
|
||||||
|
|
||||||
public static class Defaults extends NumberFieldMapper.Defaults {
|
public static class Defaults extends NumberFieldMapper.Defaults {
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(NumberFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new FloatFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
|
@ -86,7 +86,7 @@ public class FloatFieldMapper extends NumberFieldMapper {
|
||||||
protected Float nullValue = Defaults.NULL_VALUE;
|
protected Float nullValue = Defaults.NULL_VALUE;
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_32_BIT);
|
super(name, Defaults.FIELD_TYPE, Defaults.PRECISION_STEP_32_BIT);
|
||||||
builder = this;
|
builder = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,13 +97,22 @@ public class FloatFieldMapper extends NumberFieldMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FloatFieldMapper build(BuilderContext context) {
|
public FloatFieldMapper build(BuilderContext context) {
|
||||||
fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
|
setupFieldType(context);
|
||||||
FloatFieldMapper fieldMapper = new FloatFieldMapper(buildNames(context),
|
FloatFieldMapper fieldMapper = new FloatFieldMapper(fieldType, docValues, nullValue, ignoreMalformed(context), coerce(context),
|
||||||
fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue, ignoreMalformed(context), coerce(context),
|
fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
||||||
similarity, normsLoading, fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
|
||||||
fieldMapper.includeInAll(includeInAll);
|
fieldMapper.includeInAll(includeInAll);
|
||||||
return fieldMapper;
|
return fieldMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NamedAnalyzer makeNumberAnalyzer(int precisionStep) {
|
||||||
|
return NumericFloatAnalyzer.buildNamedAnalyzer(precisionStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int maxPrecisionStep() {
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TypeParser implements Mapper.TypeParser {
|
public static class TypeParser implements Mapper.TypeParser {
|
||||||
|
@ -127,23 +136,83 @@ public class FloatFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class FloatFieldType extends NumberFieldType {
|
||||||
|
|
||||||
|
public FloatFieldType() {}
|
||||||
|
|
||||||
|
protected FloatFieldType(FloatFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NumberFieldType clone() {
|
||||||
|
return new FloatFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Float value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).floatValue();
|
||||||
|
}
|
||||||
|
if (value instanceof BytesRef) {
|
||||||
|
return Numbers.bytesToFloat((BytesRef) value);
|
||||||
|
}
|
||||||
|
return Float.parseFloat(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BytesRef indexedValueForSearch(Object value) {
|
||||||
|
int intValue = NumericUtils.floatToSortableInt(parseValue(value));
|
||||||
|
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
||||||
|
NumericUtils.intToPrefixCoded(intValue, 0, bytesRef); // 0 because of exact match
|
||||||
|
return bytesRef.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
||||||
|
return NumericRangeQuery.newFloatRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
lowerTerm == null ? null : parseValue(lowerTerm),
|
||||||
|
upperTerm == null ? null : parseValue(upperTerm),
|
||||||
|
includeLower, includeUpper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
||||||
|
float iValue = Float.parseFloat(value);
|
||||||
|
final float iSim = fuzziness.asFloat();
|
||||||
|
return NumericRangeQuery.newFloatRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
iValue - iSim,
|
||||||
|
iValue + iSim,
|
||||||
|
true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
||||||
|
float minValue = NumericUtils.sortableIntToFloat(NumericUtils.getMinInt(terms));
|
||||||
|
float maxValue = NumericUtils.sortableIntToFloat(NumericUtils.getMaxInt(terms));
|
||||||
|
return new FieldStats.Float(
|
||||||
|
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), minValue, maxValue
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Float nullValue;
|
private Float nullValue;
|
||||||
|
|
||||||
private String nullValueAsString;
|
private String nullValueAsString;
|
||||||
|
|
||||||
protected FloatFieldMapper(Names names, int precisionStep, float boost, FieldType fieldType, Boolean docValues,
|
protected FloatFieldMapper(MappedFieldType fieldType, Boolean docValues,
|
||||||
Float nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
Float nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
||||||
SimilarityProvider similarity, Loading normsLoading, @Nullable Settings fieldDataSettings,
|
@Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||||
Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||||
super(names, precisionStep, boost, fieldType, docValues, ignoreMalformed, coerce,
|
|
||||||
NumericFloatAnalyzer.buildNamedAnalyzer(precisionStep), NumericFloatAnalyzer.buildNamedAnalyzer(Integer.MAX_VALUE),
|
|
||||||
similarity, normsLoading, fieldDataSettings, indexSettings, multiFields, copyTo);
|
|
||||||
this.nullValue = nullValue;
|
this.nullValue = nullValue;
|
||||||
this.nullValueAsString = nullValue == null ? null : nullValue.toString();
|
this.nullValueAsString = nullValue == null ? null : nullValue.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,34 +221,7 @@ public class FloatFieldMapper extends NumberFieldMapper {
|
||||||
return new FieldDataType("float");
|
return new FieldDataType("float");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private static float parseValue(Object value) {
|
||||||
protected int maxPrecisionStep() {
|
|
||||||
return 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Float value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (value instanceof Number) {
|
|
||||||
return ((Number) value).floatValue();
|
|
||||||
}
|
|
||||||
if (value instanceof BytesRef) {
|
|
||||||
return Numbers.bytesToFloat((BytesRef) value);
|
|
||||||
}
|
|
||||||
return Float.parseFloat(value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BytesRef indexedValueForSearch(Object value) {
|
|
||||||
int intValue = NumericUtils.floatToSortableInt(parseValue(value));
|
|
||||||
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
|
||||||
NumericUtils.intToPrefixCoded(intValue, 0, bytesRef); // 0 because of exact match
|
|
||||||
return bytesRef.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private float parseValue(Object value) {
|
|
||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
return ((Number) value).floatValue();
|
return ((Number) value).floatValue();
|
||||||
}
|
}
|
||||||
|
@ -189,24 +231,6 @@ public class FloatFieldMapper extends NumberFieldMapper {
|
||||||
return Float.parseFloat(value.toString());
|
return Float.parseFloat(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
|
||||||
float iValue = Float.parseFloat(value);
|
|
||||||
final float iSim = fuzziness.asFloat();
|
|
||||||
return NumericRangeQuery.newFloatRange(names.indexName(), precisionStep,
|
|
||||||
iValue - iSim,
|
|
||||||
iValue + iSim,
|
|
||||||
true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
|
||||||
return NumericRangeQuery.newFloatRange(names.indexName(), precisionStep,
|
|
||||||
lowerTerm == null ? null : parseValue(lowerTerm),
|
|
||||||
upperTerm == null ? null : parseValue(upperTerm),
|
|
||||||
includeLower, includeUpper);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query nullValueFilter() {
|
public Query nullValueFilter() {
|
||||||
if (nullValue == null) {
|
if (nullValue == null) {
|
||||||
|
@ -223,7 +247,7 @@ public class FloatFieldMapper extends NumberFieldMapper {
|
||||||
@Override
|
@Override
|
||||||
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
||||||
float value;
|
float value;
|
||||||
float boost = this.boost;
|
float boost = this.fieldType.boost();
|
||||||
if (context.externalValueSet()) {
|
if (context.externalValueSet()) {
|
||||||
Object externalValue = context.externalValue();
|
Object externalValue = context.externalValue();
|
||||||
if (externalValue == null) {
|
if (externalValue == null) {
|
||||||
|
@ -245,7 +269,7 @@ public class FloatFieldMapper extends NumberFieldMapper {
|
||||||
value = ((Number) externalValue).floatValue();
|
value = ((Number) externalValue).floatValue();
|
||||||
}
|
}
|
||||||
if (context.includeInAll(includeInAll, this)) {
|
if (context.includeInAll(includeInAll, this)) {
|
||||||
context.allEntries().addText(names.fullName(), Float.toString(value), boost);
|
context.allEntries().addText(fieldType.names().fullName(), Float.toString(value), boost);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
XContentParser parser = context.parser();
|
XContentParser parser = context.parser();
|
||||||
|
@ -256,7 +280,7 @@ public class FloatFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
value = nullValue;
|
value = nullValue;
|
||||||
if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) {
|
if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) {
|
||||||
context.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
context.allEntries().addText(fieldType.names().fullName(), nullValueAsString, boost);
|
||||||
}
|
}
|
||||||
} else if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
|
} else if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
|
@ -285,26 +309,26 @@ public class FloatFieldMapper extends NumberFieldMapper {
|
||||||
} else {
|
} else {
|
||||||
value = parser.floatValue(coerce.value());
|
value = parser.floatValue(coerce.value());
|
||||||
if (context.includeInAll(includeInAll, this)) {
|
if (context.includeInAll(includeInAll, this)) {
|
||||||
context.allEntries().addText(names.fullName(), parser.text(), boost);
|
context.allEntries().addText(fieldType.names().fullName(), parser.text(), boost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
||||||
CustomFloatNumericField field = new CustomFloatNumericField(this, value, fieldType);
|
CustomFloatNumericField field = new CustomFloatNumericField(this, value, (NumberFieldType)fieldType);
|
||||||
field.setBoost(boost);
|
field.setBoost(boost);
|
||||||
fields.add(field);
|
fields.add(field);
|
||||||
}
|
}
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
if (useSortedNumericDocValues) {
|
if (useSortedNumericDocValues) {
|
||||||
addDocValue(context, fields, NumericUtils.floatToSortableInt(value));
|
addDocValue(context, fields, floatToSortableInt(value));
|
||||||
} else {
|
} else {
|
||||||
CustomFloatNumericDocValuesField field = (CustomFloatNumericDocValuesField) context.doc().getByKey(names().indexName());
|
CustomFloatNumericDocValuesField field = (CustomFloatNumericDocValuesField) context.doc().getByKey(fieldType().names().indexName());
|
||||||
if (field != null) {
|
if (field != null) {
|
||||||
field.add(value);
|
field.add(value);
|
||||||
} else {
|
} else {
|
||||||
field = new CustomFloatNumericDocValuesField(names().indexName(), value);
|
field = new CustomFloatNumericDocValuesField(fieldType().names().indexName(), value);
|
||||||
context.doc().addWithKey(names().indexName(), field);
|
context.doc().addWithKey(fieldType().names().indexName(), field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,8 +356,8 @@ public class FloatFieldMapper extends NumberFieldMapper {
|
||||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||||
super.doXContentBody(builder, includeDefaults, params);
|
super.doXContentBody(builder, includeDefaults, params);
|
||||||
|
|
||||||
if (includeDefaults || precisionStep != Defaults.PRECISION_STEP_32_BIT) {
|
if (includeDefaults || fieldType.numericPrecisionStep() != Defaults.PRECISION_STEP_32_BIT) {
|
||||||
builder.field("precision_step", precisionStep);
|
builder.field("precision_step", fieldType.numericPrecisionStep());
|
||||||
}
|
}
|
||||||
if (includeDefaults || nullValue != null) {
|
if (includeDefaults || nullValue != null) {
|
||||||
builder.field("null_value", nullValue);
|
builder.field("null_value", nullValue);
|
||||||
|
@ -346,22 +370,13 @@ public class FloatFieldMapper extends NumberFieldMapper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
|
||||||
float minValue = NumericUtils.sortableIntToFloat(NumericUtils.getMinInt(terms));
|
|
||||||
float maxValue = NumericUtils.sortableIntToFloat(NumericUtils.getMaxInt(terms));
|
|
||||||
return new FieldStats.Float(
|
|
||||||
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), minValue, maxValue
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CustomFloatNumericField extends CustomNumericField {
|
public static class CustomFloatNumericField extends CustomNumericField {
|
||||||
|
|
||||||
private final float number;
|
private final float number;
|
||||||
|
|
||||||
private final NumberFieldMapper mapper;
|
private final NumberFieldMapper mapper;
|
||||||
|
|
||||||
public CustomFloatNumericField(NumberFieldMapper mapper, float number, FieldType fieldType) {
|
public CustomFloatNumericField(NumberFieldMapper mapper, float number, NumberFieldType fieldType) {
|
||||||
super(mapper, number, fieldType);
|
super(mapper, number, fieldType);
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
this.number = number;
|
this.number = number;
|
||||||
|
@ -383,12 +398,6 @@ public class FloatFieldMapper extends NumberFieldMapper {
|
||||||
|
|
||||||
public static class CustomFloatNumericDocValuesField extends CustomNumericDocValuesField {
|
public static class CustomFloatNumericDocValuesField extends CustomNumericDocValuesField {
|
||||||
|
|
||||||
public static final FieldType TYPE = new FieldType();
|
|
||||||
static {
|
|
||||||
TYPE.setDocValuesType(DocValuesType.BINARY);
|
|
||||||
TYPE.freeze();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final FloatArrayList values;
|
private final FloatArrayList values;
|
||||||
|
|
||||||
public CustomFloatNumericDocValuesField(String name, float value) {
|
public CustomFloatNumericDocValuesField(String name, float value) {
|
||||||
|
|
|
@ -22,7 +22,6 @@ package org.elasticsearch.index.mapper.core;
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.index.Terms;
|
import org.apache.lucene.index.Terms;
|
||||||
import org.apache.lucene.search.ConstantScoreQuery;
|
import org.apache.lucene.search.ConstantScoreQuery;
|
||||||
|
@ -40,15 +39,16 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.unit.Fuzziness;
|
import org.elasticsearch.common.unit.Fuzziness;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
import org.elasticsearch.index.analysis.NumericIntegerAnalyzer;
|
import org.elasticsearch.index.analysis.NumericIntegerAnalyzer;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
import org.elasticsearch.index.mapper.MergeResult;
|
import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -67,7 +67,7 @@ public class IntegerFieldMapper extends NumberFieldMapper {
|
||||||
public static final String CONTENT_TYPE = "integer";
|
public static final String CONTENT_TYPE = "integer";
|
||||||
|
|
||||||
public static class Defaults extends NumberFieldMapper.Defaults {
|
public static class Defaults extends NumberFieldMapper.Defaults {
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(NumberFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new IntegerFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
|
@ -81,7 +81,7 @@ public class IntegerFieldMapper extends NumberFieldMapper {
|
||||||
protected Integer nullValue = Defaults.NULL_VALUE;
|
protected Integer nullValue = Defaults.NULL_VALUE;
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_32_BIT);
|
super(name, Defaults.FIELD_TYPE, Defaults.PRECISION_STEP_32_BIT);
|
||||||
builder = this;
|
builder = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,13 +92,23 @@ public class IntegerFieldMapper extends NumberFieldMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IntegerFieldMapper build(BuilderContext context) {
|
public IntegerFieldMapper build(BuilderContext context) {
|
||||||
fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
|
setupFieldType(context);
|
||||||
IntegerFieldMapper fieldMapper = new IntegerFieldMapper(buildNames(context), fieldType.numericPrecisionStep(), boost, fieldType, docValues,
|
IntegerFieldMapper fieldMapper = new IntegerFieldMapper(fieldType, docValues,
|
||||||
nullValue, ignoreMalformed(context), coerce(context), similarity, normsLoading, fieldDataSettings,
|
nullValue, ignoreMalformed(context), coerce(context), fieldDataSettings,
|
||||||
context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
||||||
fieldMapper.includeInAll(includeInAll);
|
fieldMapper.includeInAll(includeInAll);
|
||||||
return fieldMapper;
|
return fieldMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NamedAnalyzer makeNumberAnalyzer(int precisionStep) {
|
||||||
|
return NumericIntegerAnalyzer.buildNamedAnalyzer(precisionStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int maxPrecisionStep() {
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TypeParser implements Mapper.TypeParser {
|
public static class TypeParser implements Mapper.TypeParser {
|
||||||
|
@ -122,23 +132,83 @@ public class IntegerFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class IntegerFieldType extends NumberFieldType {
|
||||||
|
|
||||||
|
public IntegerFieldType() {}
|
||||||
|
|
||||||
|
protected IntegerFieldType(IntegerFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NumberFieldType clone() {
|
||||||
|
return new IntegerFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
if (value instanceof BytesRef) {
|
||||||
|
return Numbers.bytesToInt((BytesRef) value);
|
||||||
|
}
|
||||||
|
return Integer.parseInt(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BytesRef indexedValueForSearch(Object value) {
|
||||||
|
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
||||||
|
NumericUtils.intToPrefixCoded(parseValue(value), 0, bytesRef); // 0 because of exact match
|
||||||
|
return bytesRef.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
||||||
|
return NumericRangeQuery.newIntRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
lowerTerm == null ? null : parseValue(lowerTerm),
|
||||||
|
upperTerm == null ? null : parseValue(upperTerm),
|
||||||
|
includeLower, includeUpper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
||||||
|
int iValue = Integer.parseInt(value);
|
||||||
|
int iSim = fuzziness.asInt();
|
||||||
|
return NumericRangeQuery.newIntRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
iValue - iSim,
|
||||||
|
iValue + iSim,
|
||||||
|
true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
||||||
|
long minValue = NumericUtils.getMinInt(terms);
|
||||||
|
long maxValue = NumericUtils.getMaxInt(terms);
|
||||||
|
return new FieldStats.Long(
|
||||||
|
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), minValue, maxValue
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Integer nullValue;
|
private Integer nullValue;
|
||||||
|
|
||||||
private String nullValueAsString;
|
private String nullValueAsString;
|
||||||
|
|
||||||
protected IntegerFieldMapper(Names names, int precisionStep, float boost, FieldType fieldType, Boolean docValues,
|
protected IntegerFieldMapper(MappedFieldType fieldType, Boolean docValues,
|
||||||
Integer nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
Integer nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
||||||
SimilarityProvider similarity, Loading normsLoading, @Nullable Settings fieldDataSettings,
|
@Nullable Settings fieldDataSettings,
|
||||||
Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||||
super(names, precisionStep, boost, fieldType, docValues, ignoreMalformed, coerce,
|
super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||||
NumericIntegerAnalyzer.buildNamedAnalyzer(precisionStep), NumericIntegerAnalyzer.buildNamedAnalyzer(Integer.MAX_VALUE),
|
|
||||||
similarity, normsLoading, fieldDataSettings, indexSettings, multiFields, copyTo);
|
|
||||||
this.nullValue = nullValue;
|
this.nullValue = nullValue;
|
||||||
this.nullValueAsString = nullValue == null ? null : nullValue.toString();
|
this.nullValueAsString = nullValue == null ? null : nullValue.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,33 +217,9 @@ public class IntegerFieldMapper extends NumberFieldMapper {
|
||||||
return new FieldDataType("int");
|
return new FieldDataType("int");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int maxPrecisionStep() {
|
|
||||||
return 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (value instanceof Number) {
|
|
||||||
return ((Number) value).intValue();
|
|
||||||
}
|
|
||||||
if (value instanceof BytesRef) {
|
|
||||||
return Numbers.bytesToInt((BytesRef) value);
|
|
||||||
}
|
|
||||||
return Integer.parseInt(value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
private static int parseValue(Object value) {
|
||||||
public BytesRef indexedValueForSearch(Object value) {
|
|
||||||
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
|
||||||
NumericUtils.intToPrefixCoded(parseValue(value), 0, bytesRef); // 0 because of exact match
|
|
||||||
return bytesRef.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private int parseValue(Object value) {
|
|
||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
return ((Number) value).intValue();
|
return ((Number) value).intValue();
|
||||||
}
|
}
|
||||||
|
@ -183,24 +229,6 @@ public class IntegerFieldMapper extends NumberFieldMapper {
|
||||||
return Integer.parseInt(value.toString());
|
return Integer.parseInt(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
|
||||||
int iValue = Integer.parseInt(value);
|
|
||||||
int iSim = fuzziness.asInt();
|
|
||||||
return NumericRangeQuery.newIntRange(names.indexName(), precisionStep,
|
|
||||||
iValue - iSim,
|
|
||||||
iValue + iSim,
|
|
||||||
true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
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
|
@Override
|
||||||
public Query nullValueFilter() {
|
public Query nullValueFilter() {
|
||||||
if (nullValue == null) {
|
if (nullValue == null) {
|
||||||
|
@ -217,7 +245,7 @@ public class IntegerFieldMapper extends NumberFieldMapper {
|
||||||
@Override
|
@Override
|
||||||
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
||||||
int value;
|
int value;
|
||||||
float boost = this.boost;
|
float boost = this.fieldType.boost();
|
||||||
if (context.externalValueSet()) {
|
if (context.externalValueSet()) {
|
||||||
Object externalValue = context.externalValue();
|
Object externalValue = context.externalValue();
|
||||||
if (externalValue == null) {
|
if (externalValue == null) {
|
||||||
|
@ -239,7 +267,7 @@ public class IntegerFieldMapper extends NumberFieldMapper {
|
||||||
value = ((Number) externalValue).intValue();
|
value = ((Number) externalValue).intValue();
|
||||||
}
|
}
|
||||||
if (context.includeInAll(includeInAll, this)) {
|
if (context.includeInAll(includeInAll, this)) {
|
||||||
context.allEntries().addText(names.fullName(), Integer.toString(value), boost);
|
context.allEntries().addText(fieldType.names().fullName(), Integer.toString(value), boost);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
XContentParser parser = context.parser();
|
XContentParser parser = context.parser();
|
||||||
|
@ -250,7 +278,7 @@ public class IntegerFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
value = nullValue;
|
value = nullValue;
|
||||||
if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) {
|
if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) {
|
||||||
context.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
context.allEntries().addText(fieldType.names().fullName(), nullValueAsString, boost);
|
||||||
}
|
}
|
||||||
} else if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
|
} else if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
|
@ -279,7 +307,7 @@ public class IntegerFieldMapper extends NumberFieldMapper {
|
||||||
} else {
|
} else {
|
||||||
value = parser.intValue(coerce.value());
|
value = parser.intValue(coerce.value());
|
||||||
if (context.includeInAll(includeInAll, this)) {
|
if (context.includeInAll(includeInAll, this)) {
|
||||||
context.allEntries().addText(names.fullName(), parser.text(), boost);
|
context.allEntries().addText(fieldType.names().fullName(), parser.text(), boost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,11 +316,11 @@ public class IntegerFieldMapper extends NumberFieldMapper {
|
||||||
|
|
||||||
protected void addIntegerFields(ParseContext context, List<Field> fields, int value, float boost) {
|
protected void addIntegerFields(ParseContext context, List<Field> fields, int value, float boost) {
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
||||||
CustomIntegerNumericField field = new CustomIntegerNumericField(this, value, fieldType);
|
CustomIntegerNumericField field = new CustomIntegerNumericField(this, value, (NumberFieldType)fieldType);
|
||||||
field.setBoost(boost);
|
field.setBoost(boost);
|
||||||
fields.add(field);
|
fields.add(field);
|
||||||
}
|
}
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
addDocValue(context, fields, value);
|
addDocValue(context, fields, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,8 +350,8 @@ public class IntegerFieldMapper extends NumberFieldMapper {
|
||||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||||
super.doXContentBody(builder, includeDefaults, params);
|
super.doXContentBody(builder, includeDefaults, params);
|
||||||
|
|
||||||
if (includeDefaults || precisionStep != Defaults.PRECISION_STEP_32_BIT) {
|
if (includeDefaults || fieldType.numericPrecisionStep() != Defaults.PRECISION_STEP_32_BIT) {
|
||||||
builder.field("precision_step", precisionStep);
|
builder.field("precision_step", fieldType.numericPrecisionStep());
|
||||||
}
|
}
|
||||||
if (includeDefaults || nullValue != null) {
|
if (includeDefaults || nullValue != null) {
|
||||||
builder.field("null_value", nullValue);
|
builder.field("null_value", nullValue);
|
||||||
|
@ -336,22 +364,13 @@ public class IntegerFieldMapper extends NumberFieldMapper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
|
||||||
long minValue = NumericUtils.getMinInt(terms);
|
|
||||||
long maxValue = NumericUtils.getMaxInt(terms);
|
|
||||||
return new FieldStats.Long(
|
|
||||||
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), minValue, maxValue
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CustomIntegerNumericField extends CustomNumericField {
|
public static class CustomIntegerNumericField extends CustomNumericField {
|
||||||
|
|
||||||
private final int number;
|
private final int number;
|
||||||
|
|
||||||
private final NumberFieldMapper mapper;
|
private final NumberFieldMapper mapper;
|
||||||
|
|
||||||
public CustomIntegerNumericField(NumberFieldMapper mapper, int number, FieldType fieldType) {
|
public CustomIntegerNumericField(NumberFieldMapper mapper, int number, MappedFieldType fieldType) {
|
||||||
super(mapper, number, fieldType);
|
super(mapper, number, fieldType);
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
this.number = number;
|
this.number = number;
|
||||||
|
|
|
@ -22,7 +22,6 @@ package org.elasticsearch.index.mapper.core;
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.index.Terms;
|
import org.apache.lucene.index.Terms;
|
||||||
import org.apache.lucene.search.ConstantScoreQuery;
|
import org.apache.lucene.search.ConstantScoreQuery;
|
||||||
|
@ -40,15 +39,16 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.unit.Fuzziness;
|
import org.elasticsearch.common.unit.Fuzziness;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
import org.elasticsearch.index.analysis.NumericLongAnalyzer;
|
import org.elasticsearch.index.analysis.NumericLongAnalyzer;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
import org.elasticsearch.index.mapper.MergeResult;
|
import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -67,7 +67,7 @@ public class LongFieldMapper extends NumberFieldMapper {
|
||||||
public static final String CONTENT_TYPE = "long";
|
public static final String CONTENT_TYPE = "long";
|
||||||
|
|
||||||
public static class Defaults extends NumberFieldMapper.Defaults {
|
public static class Defaults extends NumberFieldMapper.Defaults {
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(NumberFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new LongFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
|
@ -81,7 +81,7 @@ public class LongFieldMapper extends NumberFieldMapper {
|
||||||
protected Long nullValue = Defaults.NULL_VALUE;
|
protected Long nullValue = Defaults.NULL_VALUE;
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_64_BIT);
|
super(name, Defaults.FIELD_TYPE, Defaults.PRECISION_STEP_64_BIT);
|
||||||
builder = this;
|
builder = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,13 +92,22 @@ public class LongFieldMapper extends NumberFieldMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LongFieldMapper build(BuilderContext context) {
|
public LongFieldMapper build(BuilderContext context) {
|
||||||
fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
|
setupFieldType(context);
|
||||||
LongFieldMapper fieldMapper = new LongFieldMapper(buildNames(context), fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue,
|
LongFieldMapper fieldMapper = new LongFieldMapper(fieldType, docValues, nullValue,
|
||||||
ignoreMalformed(context), coerce(context), similarity, normsLoading,
|
ignoreMalformed(context), coerce(context), fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
||||||
fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
|
||||||
fieldMapper.includeInAll(includeInAll);
|
fieldMapper.includeInAll(includeInAll);
|
||||||
return fieldMapper;
|
return fieldMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NamedAnalyzer makeNumberAnalyzer(int precisionStep) {
|
||||||
|
return NumericLongAnalyzer.buildNamedAnalyzer(precisionStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int maxPrecisionStep() {
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TypeParser implements Mapper.TypeParser {
|
public static class TypeParser implements Mapper.TypeParser {
|
||||||
|
@ -122,23 +131,83 @@ public class LongFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class LongFieldType extends NumberFieldType {
|
||||||
|
|
||||||
|
public LongFieldType() {}
|
||||||
|
|
||||||
|
protected LongFieldType(LongFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NumberFieldType clone() {
|
||||||
|
return new LongFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).longValue();
|
||||||
|
}
|
||||||
|
if (value instanceof BytesRef) {
|
||||||
|
return Numbers.bytesToLong((BytesRef) value);
|
||||||
|
}
|
||||||
|
return Long.parseLong(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BytesRef indexedValueForSearch(Object value) {
|
||||||
|
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
||||||
|
NumericUtils.longToPrefixCoded(parseLongValue(value), 0, bytesRef); // 0 because of exact match
|
||||||
|
return bytesRef.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
||||||
|
return NumericRangeQuery.newLongRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
lowerTerm == null ? null : parseLongValue(lowerTerm),
|
||||||
|
upperTerm == null ? null : parseLongValue(upperTerm),
|
||||||
|
includeLower, includeUpper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
||||||
|
long iValue = Long.parseLong(value);
|
||||||
|
final long iSim = fuzziness.asLong();
|
||||||
|
return NumericRangeQuery.newLongRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
iValue - iSim,
|
||||||
|
iValue + iSim,
|
||||||
|
true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
||||||
|
long minValue = NumericUtils.getMinLong(terms);
|
||||||
|
long maxValue = NumericUtils.getMaxLong(terms);
|
||||||
|
return new FieldStats.Long(
|
||||||
|
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), minValue, maxValue
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Long nullValue;
|
private Long nullValue;
|
||||||
|
|
||||||
private String nullValueAsString;
|
private String nullValueAsString;
|
||||||
|
|
||||||
protected LongFieldMapper(Names names, int precisionStep, float boost, FieldType fieldType, Boolean docValues,
|
protected LongFieldMapper(MappedFieldType fieldType, Boolean docValues,
|
||||||
Long nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
Long nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
||||||
SimilarityProvider similarity, Loading normsLoading, @Nullable Settings fieldDataSettings,
|
@Nullable Settings fieldDataSettings,
|
||||||
Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||||
super(names, precisionStep, boost, fieldType, docValues, ignoreMalformed, coerce,
|
super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||||
NumericLongAnalyzer.buildNamedAnalyzer(precisionStep), NumericLongAnalyzer.buildNamedAnalyzer(Integer.MAX_VALUE),
|
|
||||||
similarity, normsLoading, fieldDataSettings, indexSettings, multiFields, copyTo);
|
|
||||||
this.nullValue = nullValue;
|
this.nullValue = nullValue;
|
||||||
this.nullValueAsString = nullValue == null ? null : nullValue.toString();
|
this.nullValueAsString = nullValue == null ? null : nullValue.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,50 +216,6 @@ public class LongFieldMapper extends NumberFieldMapper {
|
||||||
return new FieldDataType("long");
|
return new FieldDataType("long");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int maxPrecisionStep() {
|
|
||||||
return 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (value instanceof Number) {
|
|
||||||
return ((Number) value).longValue();
|
|
||||||
}
|
|
||||||
if (value instanceof BytesRef) {
|
|
||||||
return Numbers.bytesToLong((BytesRef) value);
|
|
||||||
}
|
|
||||||
return Long.parseLong(value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BytesRef indexedValueForSearch(Object value) {
|
|
||||||
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
|
||||||
NumericUtils.longToPrefixCoded(parseLongValue(value), 0, bytesRef); // 0 because of exact match
|
|
||||||
return bytesRef.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
|
||||||
long iValue = Long.parseLong(value);
|
|
||||||
final long iSim = fuzziness.asLong();
|
|
||||||
return NumericRangeQuery.newLongRange(names.indexName(), precisionStep,
|
|
||||||
iValue - iSim,
|
|
||||||
iValue + iSim,
|
|
||||||
true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
|
||||||
return NumericRangeQuery.newLongRange(names.indexName(), precisionStep,
|
|
||||||
lowerTerm == null ? null : parseLongValue(lowerTerm),
|
|
||||||
upperTerm == null ? null : parseLongValue(upperTerm),
|
|
||||||
includeLower, includeUpper);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query nullValueFilter() {
|
public Query nullValueFilter() {
|
||||||
if (nullValue == null) {
|
if (nullValue == null) {
|
||||||
|
@ -207,7 +232,7 @@ public class LongFieldMapper extends NumberFieldMapper {
|
||||||
@Override
|
@Override
|
||||||
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
||||||
long value;
|
long value;
|
||||||
float boost = this.boost;
|
float boost = this.fieldType.boost();
|
||||||
if (context.externalValueSet()) {
|
if (context.externalValueSet()) {
|
||||||
Object externalValue = context.externalValue();
|
Object externalValue = context.externalValue();
|
||||||
if (externalValue == null) {
|
if (externalValue == null) {
|
||||||
|
@ -229,7 +254,7 @@ public class LongFieldMapper extends NumberFieldMapper {
|
||||||
value = ((Number) externalValue).longValue();
|
value = ((Number) externalValue).longValue();
|
||||||
}
|
}
|
||||||
if (context.includeInAll(includeInAll, this)) {
|
if (context.includeInAll(includeInAll, this)) {
|
||||||
context.allEntries().addText(names.fullName(), Long.toString(value), boost);
|
context.allEntries().addText(fieldType.names().fullName(), Long.toString(value), boost);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
XContentParser parser = context.parser();
|
XContentParser parser = context.parser();
|
||||||
|
@ -240,7 +265,7 @@ public class LongFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
value = nullValue;
|
value = nullValue;
|
||||||
if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) {
|
if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) {
|
||||||
context.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
context.allEntries().addText(fieldType.names().fullName(), nullValueAsString, boost);
|
||||||
}
|
}
|
||||||
} else if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
|
} else if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
|
@ -269,16 +294,16 @@ public class LongFieldMapper extends NumberFieldMapper {
|
||||||
} else {
|
} else {
|
||||||
value = parser.longValue(coerce.value());
|
value = parser.longValue(coerce.value());
|
||||||
if (context.includeInAll(includeInAll, this)) {
|
if (context.includeInAll(includeInAll, this)) {
|
||||||
context.allEntries().addText(names.fullName(), parser.text(), boost);
|
context.allEntries().addText(fieldType.names().fullName(), parser.text(), boost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
||||||
CustomLongNumericField field = new CustomLongNumericField(this, value, fieldType);
|
CustomLongNumericField field = new CustomLongNumericField(this, value, (NumberFieldType)fieldType);
|
||||||
field.setBoost(boost);
|
field.setBoost(boost);
|
||||||
fields.add(field);
|
fields.add(field);
|
||||||
}
|
}
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
addDocValue(context, fields, value);
|
addDocValue(context, fields, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,8 +329,8 @@ public class LongFieldMapper extends NumberFieldMapper {
|
||||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||||
super.doXContentBody(builder, includeDefaults, params);
|
super.doXContentBody(builder, includeDefaults, params);
|
||||||
|
|
||||||
if (includeDefaults || precisionStep != Defaults.PRECISION_STEP_64_BIT) {
|
if (includeDefaults || fieldType.numericPrecisionStep() != Defaults.PRECISION_STEP_64_BIT) {
|
||||||
builder.field("precision_step", precisionStep);
|
builder.field("precision_step", fieldType.numericPrecisionStep());
|
||||||
}
|
}
|
||||||
if (includeDefaults || nullValue != null) {
|
if (includeDefaults || nullValue != null) {
|
||||||
builder.field("null_value", nullValue);
|
builder.field("null_value", nullValue);
|
||||||
|
@ -317,22 +342,13 @@ public class LongFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
|
||||||
long minValue = NumericUtils.getMinLong(terms);
|
|
||||||
long maxValue = NumericUtils.getMaxLong(terms);
|
|
||||||
return new FieldStats.Long(
|
|
||||||
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), minValue, maxValue
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CustomLongNumericField extends CustomNumericField {
|
public static class CustomLongNumericField extends CustomNumericField {
|
||||||
|
|
||||||
private final long number;
|
private final long number;
|
||||||
|
|
||||||
private final NumberFieldMapper mapper;
|
private final NumberFieldMapper mapper;
|
||||||
|
|
||||||
public CustomLongNumericField(NumberFieldMapper mapper, long number, FieldType fieldType) {
|
public CustomLongNumericField(NumberFieldMapper mapper, long number, MappedFieldType fieldType) {
|
||||||
super(mapper, number, fieldType);
|
super(mapper, number, fieldType);
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
this.number = number;
|
this.number = number;
|
||||||
|
|
|
@ -20,13 +20,16 @@
|
||||||
package org.elasticsearch.index.mapper.core;
|
package org.elasticsearch.index.mapper.core;
|
||||||
|
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.common.Explicit;
|
import org.elasticsearch.common.Explicit;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.hash.MurmurHash3;
|
import org.elasticsearch.common.hash.MurmurHash3;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
|
import org.elasticsearch.index.analysis.NumericDateAnalyzer;
|
||||||
|
import org.elasticsearch.index.analysis.NumericLongAnalyzer;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
|
@ -36,7 +39,6 @@ import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue;
|
|
||||||
import static org.elasticsearch.index.mapper.MapperBuilders.murmur3Field;
|
import static org.elasticsearch.index.mapper.MapperBuilders.murmur3Field;
|
||||||
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
|
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
|
||||||
|
|
||||||
|
@ -50,20 +52,30 @@ public class Murmur3FieldMapper extends LongFieldMapper {
|
||||||
public static class Builder extends NumberFieldMapper.Builder<Builder, Murmur3FieldMapper> {
|
public static class Builder extends NumberFieldMapper.Builder<Builder, Murmur3FieldMapper> {
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE), Integer.MAX_VALUE);
|
super(name, Defaults.FIELD_TYPE, Integer.MAX_VALUE);
|
||||||
builder = this;
|
builder = this;
|
||||||
builder.precisionStep(Integer.MAX_VALUE);
|
builder.precisionStep(Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Murmur3FieldMapper build(BuilderContext context) {
|
public Murmur3FieldMapper build(BuilderContext context) {
|
||||||
fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
|
setupFieldType(context);
|
||||||
Murmur3FieldMapper fieldMapper = new Murmur3FieldMapper(buildNames(context), fieldType.numericPrecisionStep(), boost, fieldType, docValues, null,
|
Murmur3FieldMapper fieldMapper = new Murmur3FieldMapper(fieldType, docValues, null,
|
||||||
ignoreMalformed(context), coerce(context), similarity, normsLoading,
|
ignoreMalformed(context), coerce(context),
|
||||||
fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
||||||
fieldMapper.includeInAll(includeInAll);
|
fieldMapper.includeInAll(includeInAll);
|
||||||
return fieldMapper;
|
return fieldMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NamedAnalyzer makeNumberAnalyzer(int precisionStep) {
|
||||||
|
return NumericLongAnalyzer.buildNamedAnalyzer(precisionStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int maxPrecisionStep() {
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TypeParser implements Mapper.TypeParser {
|
public static class TypeParser implements Mapper.TypeParser {
|
||||||
|
@ -92,13 +104,12 @@ public class Murmur3FieldMapper extends LongFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Murmur3FieldMapper(Names names, int precisionStep, float boost, FieldType fieldType, Boolean docValues,
|
protected Murmur3FieldMapper(MappedFieldType fieldType, Boolean docValues,
|
||||||
Long nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
Long nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
||||||
SimilarityProvider similarity, Loading normsLoading, @Nullable Settings fieldDataSettings,
|
@Nullable Settings fieldDataSettings,
|
||||||
Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||||
super(names, precisionStep, boost, fieldType, docValues, nullValue, ignoreMalformed, coerce,
|
super(fieldType, docValues, nullValue, ignoreMalformed, coerce,
|
||||||
similarity, normsLoading, fieldDataSettings,
|
fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||||
indexSettings, multiFields, copyTo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -31,9 +31,7 @@ import org.apache.lucene.index.DocValuesType;
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.index.IndexableField;
|
import org.apache.lucene.index.IndexableField;
|
||||||
import org.apache.lucene.index.IndexableFieldType;
|
import org.apache.lucene.index.IndexableFieldType;
|
||||||
import org.apache.lucene.index.Term;
|
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.TermQuery;
|
|
||||||
import org.apache.lucene.store.ByteArrayDataOutput;
|
import org.apache.lucene.store.ByteArrayDataOutput;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
|
@ -45,14 +43,13 @@ import org.elasticsearch.common.util.ByteUtils;
|
||||||
import org.elasticsearch.common.util.CollectionUtils;
|
import org.elasticsearch.common.util.CollectionUtils;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
import org.elasticsearch.index.mapper.MergeResult;
|
import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.mapper.internal.AllFieldMapper;
|
import org.elasticsearch.index.mapper.internal.AllFieldMapper;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
|
||||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
@ -70,16 +67,6 @@ public abstract class NumberFieldMapper extends AbstractFieldMapper implements A
|
||||||
public static final int PRECISION_STEP_32_BIT = 8; // 4tpv
|
public static final int PRECISION_STEP_32_BIT = 8; // 4tpv
|
||||||
public static final int PRECISION_STEP_64_BIT = 16; // 4tpv
|
public static final int PRECISION_STEP_64_BIT = 16; // 4tpv
|
||||||
|
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
|
||||||
|
|
||||||
static {
|
|
||||||
FIELD_TYPE.setTokenized(false);
|
|
||||||
FIELD_TYPE.setOmitNorms(true);
|
|
||||||
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
|
||||||
FIELD_TYPE.setStoreTermVectors(false);
|
|
||||||
FIELD_TYPE.freeze();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Explicit<Boolean> IGNORE_MALFORMED = new Explicit<>(false, false);
|
public static final Explicit<Boolean> IGNORE_MALFORMED = new Explicit<>(false, false);
|
||||||
public static final Explicit<Boolean> COERCE = new Explicit<>(true, false);
|
public static final Explicit<Boolean> COERCE = new Explicit<>(true, false);
|
||||||
}
|
}
|
||||||
|
@ -90,9 +77,9 @@ public abstract class NumberFieldMapper extends AbstractFieldMapper implements A
|
||||||
|
|
||||||
private Boolean coerce;
|
private Boolean coerce;
|
||||||
|
|
||||||
public Builder(String name, FieldType fieldType, int defaultPrecisionStep) {
|
public Builder(String name, MappedFieldType fieldType, int defaultPrecisionStep) {
|
||||||
super(name, fieldType);
|
super(name, fieldType);
|
||||||
fieldType.setNumericPrecisionStep(defaultPrecisionStep);
|
this.fieldType.setNumericPrecisionStep(defaultPrecisionStep);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T precisionStep(int precisionStep) {
|
public T precisionStep(int precisionStep) {
|
||||||
|
@ -129,10 +116,60 @@ public abstract class NumberFieldMapper extends AbstractFieldMapper implements A
|
||||||
}
|
}
|
||||||
return Defaults.COERCE;
|
return Defaults.COERCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setupFieldType(BuilderContext context) {
|
||||||
|
super.setupFieldType(context);
|
||||||
|
fieldType.setOmitNorms(fieldType.omitNorms() && fieldType.boost() == 1.0f);
|
||||||
|
int precisionStep = fieldType.numericPrecisionStep();
|
||||||
|
if (precisionStep <= 0 || precisionStep >= maxPrecisionStep()) {
|
||||||
|
fieldType.setNumericPrecisionStep(Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
fieldType.setIndexAnalyzer(makeNumberAnalyzer(fieldType.numericPrecisionStep()));
|
||||||
|
fieldType.setSearchAnalyzer(makeNumberAnalyzer(Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract NamedAnalyzer makeNumberAnalyzer(int precisionStep);
|
||||||
|
|
||||||
|
protected abstract int maxPrecisionStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int precisionStep;
|
public static abstract class NumberFieldType extends MappedFieldType {
|
||||||
|
|
||||||
|
public NumberFieldType() {
|
||||||
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
setTokenized(false);
|
||||||
|
setOmitNorms(true);
|
||||||
|
setIndexOptions(IndexOptions.DOCS);
|
||||||
|
setStoreTermVectors(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected NumberFieldType(NumberFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract NumberFieldType clone();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract Object value(Object value);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object valueForSearch(Object value) {
|
||||||
|
return value(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useTermQueryWithQueryString() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNumeric() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected Boolean includeInAll;
|
protected Boolean includeInAll;
|
||||||
|
|
||||||
|
@ -151,7 +188,7 @@ public abstract class NumberFieldMapper extends AbstractFieldMapper implements A
|
||||||
private ThreadLocal<NumericTokenStream> tokenStream = new ThreadLocal<NumericTokenStream>() {
|
private ThreadLocal<NumericTokenStream> tokenStream = new ThreadLocal<NumericTokenStream>() {
|
||||||
@Override
|
@Override
|
||||||
protected NumericTokenStream initialValue() {
|
protected NumericTokenStream initialValue() {
|
||||||
return new NumericTokenStream(precisionStep);
|
return new NumericTokenStream(fieldType.numericPrecisionStep());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -183,23 +220,14 @@ public abstract class NumberFieldMapper extends AbstractFieldMapper implements A
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
protected NumberFieldMapper(Names names, int precisionStep, float boost, FieldType fieldType, Boolean docValues,
|
protected NumberFieldMapper(MappedFieldType fieldType, Boolean docValues,
|
||||||
Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce, NamedAnalyzer indexAnalyzer,
|
Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce, @Nullable Settings fieldDataSettings, Settings indexSettings,
|
||||||
NamedAnalyzer searchAnalyzer, SimilarityProvider similarity,
|
|
||||||
Loading normsLoading, @Nullable Settings fieldDataSettings, Settings indexSettings,
|
|
||||||
MultiFields multiFields, CopyTo copyTo) {
|
MultiFields multiFields, CopyTo copyTo) {
|
||||||
// LUCENE 4 UPGRADE: Since we can't do anything before the super call, we have to push the boost check down to subclasses
|
// LUCENE 4 UPGRADE: Since we can't do anything before the super call, we have to push the boost check down to subclasses
|
||||||
super(names, boost, fieldType, docValues, indexAnalyzer, searchAnalyzer,
|
super(fieldType, docValues, fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||||
similarity, normsLoading, fieldDataSettings, indexSettings, multiFields, copyTo);
|
|
||||||
if (precisionStep <= 0 || precisionStep >= maxPrecisionStep()) {
|
|
||||||
this.precisionStep = Integer.MAX_VALUE;
|
|
||||||
} else {
|
|
||||||
this.precisionStep = precisionStep;
|
|
||||||
}
|
|
||||||
this.ignoreMalformed = ignoreMalformed;
|
this.ignoreMalformed = ignoreMalformed;
|
||||||
this.coerce = coerce;
|
this.coerce = coerce;
|
||||||
Version v = Version.indexCreated(indexSettings);
|
this.useSortedNumericDocValues = Version.indexCreated(indexSettings).onOrAfter(Version.V_1_4_0_Beta1);
|
||||||
this.useSortedNumericDocValues = v.onOrAfter(Version.V_1_4_0_Beta1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -221,12 +249,6 @@ public abstract class NumberFieldMapper extends AbstractFieldMapper implements A
|
||||||
includeInAll = null;
|
includeInAll = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract int maxPrecisionStep();
|
|
||||||
|
|
||||||
public int precisionStep() {
|
|
||||||
return this.precisionStep;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void parseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
protected void parseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
||||||
RuntimeException e = null;
|
RuntimeException e = null;
|
||||||
|
@ -247,41 +269,22 @@ public abstract class NumberFieldMapper extends AbstractFieldMapper implements A
|
||||||
|
|
||||||
protected final void addDocValue(ParseContext context, List<Field> fields, long value) {
|
protected final void addDocValue(ParseContext context, List<Field> fields, long value) {
|
||||||
if (useSortedNumericDocValues) {
|
if (useSortedNumericDocValues) {
|
||||||
fields.add(new SortedNumericDocValuesField(names().indexName(), value));
|
fields.add(new SortedNumericDocValuesField(fieldType().names().indexName(), value));
|
||||||
} else {
|
} else {
|
||||||
CustomLongNumericDocValuesField field = (CustomLongNumericDocValuesField) context.doc().getByKey(names().indexName());
|
CustomLongNumericDocValuesField field = (CustomLongNumericDocValuesField) context.doc().getByKey(fieldType().names().indexName());
|
||||||
if (field != null) {
|
if (field != null) {
|
||||||
field.add(value);
|
field.add(value);
|
||||||
} else {
|
} else {
|
||||||
field = new CustomLongNumericDocValuesField(names().indexName(), value);
|
field = new CustomLongNumericDocValuesField(fieldType().names().indexName(), value);
|
||||||
context.doc().addWithKey(names().indexName(), field);
|
context.doc().addWithKey(fieldType().names().indexName(), field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Use the field query created here when matching on numbers.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean useTermQueryWithQueryString() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final Query termQuery(Object value, @Nullable QueryParseContext context) {
|
|
||||||
return new TermQuery(new Term(names.indexName(), indexedValueForSearch(value)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts an object value into a double
|
* Converts an object value into a double
|
||||||
*/
|
*/
|
||||||
public double parseDoubleValue(Object value) {
|
public static double parseDoubleValue(Object value) {
|
||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
return ((Number) value).doubleValue();
|
return ((Number) value).doubleValue();
|
||||||
}
|
}
|
||||||
|
@ -296,7 +299,7 @@ public abstract class NumberFieldMapper extends AbstractFieldMapper implements A
|
||||||
/**
|
/**
|
||||||
* Converts an object value into a long
|
* Converts an object value into a long
|
||||||
*/
|
*/
|
||||||
public long parseLongValue(Object value) {
|
public static long parseLongValue(Object value) {
|
||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
return ((Number) value).longValue();
|
return ((Number) value).longValue();
|
||||||
}
|
}
|
||||||
|
@ -308,16 +311,6 @@ public abstract class NumberFieldMapper extends AbstractFieldMapper implements A
|
||||||
return Long.parseLong(value.toString());
|
return Long.parseLong(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Override the default behavior (to return the string, and return the actual Number instance).
|
|
||||||
*
|
|
||||||
* @param value
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Object valueForSearch(Object value) {
|
|
||||||
return value(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void merge(Mapper mergeWith, MergeResult mergeResult) throws MergeMappingException {
|
public void merge(Mapper mergeWith, MergeResult mergeResult) throws MergeMappingException {
|
||||||
super.merge(mergeWith, mergeResult);
|
super.merge(mergeWith, mergeResult);
|
||||||
|
@ -326,7 +319,9 @@ public abstract class NumberFieldMapper extends AbstractFieldMapper implements A
|
||||||
}
|
}
|
||||||
if (!mergeResult.simulate()) {
|
if (!mergeResult.simulate()) {
|
||||||
NumberFieldMapper nfmMergeWith = (NumberFieldMapper) mergeWith;
|
NumberFieldMapper nfmMergeWith = (NumberFieldMapper) mergeWith;
|
||||||
this.precisionStep = nfmMergeWith.precisionStep;
|
this.fieldType = this.fieldType.clone();
|
||||||
|
this.fieldType.setNumericPrecisionStep(nfmMergeWith.fieldType.numericPrecisionStep());
|
||||||
|
this.fieldType.freeze();
|
||||||
this.includeInAll = nfmMergeWith.includeInAll;
|
this.includeInAll = nfmMergeWith.includeInAll;
|
||||||
if (nfmMergeWith.ignoreMalformed.explicit()) {
|
if (nfmMergeWith.ignoreMalformed.explicit()) {
|
||||||
this.ignoreMalformed = nfmMergeWith.ignoreMalformed;
|
this.ignoreMalformed = nfmMergeWith.ignoreMalformed;
|
||||||
|
@ -342,13 +337,13 @@ public abstract class NumberFieldMapper extends AbstractFieldMapper implements A
|
||||||
}
|
}
|
||||||
|
|
||||||
protected NumericTokenStream popCachedStream() {
|
protected NumericTokenStream popCachedStream() {
|
||||||
if (precisionStep == 4) {
|
if (fieldType.numericPrecisionStep() == 4) {
|
||||||
return tokenStream4.get();
|
return tokenStream4.get();
|
||||||
} else if (precisionStep == 8) {
|
} else if (fieldType.numericPrecisionStep() == 8) {
|
||||||
return tokenStream8.get();
|
return tokenStream8.get();
|
||||||
} else if (precisionStep == 16) {
|
} else if (fieldType.numericPrecisionStep() == 16) {
|
||||||
return tokenStream16.get();
|
return tokenStream16.get();
|
||||||
} else if (precisionStep == Integer.MAX_VALUE) {
|
} else if (fieldType.numericPrecisionStep() == Integer.MAX_VALUE) {
|
||||||
return tokenStreamMax.get();
|
return tokenStreamMax.get();
|
||||||
}
|
}
|
||||||
return tokenStream.get();
|
return tokenStream.get();
|
||||||
|
@ -359,8 +354,8 @@ public abstract class NumberFieldMapper extends AbstractFieldMapper implements A
|
||||||
|
|
||||||
protected final NumberFieldMapper mapper;
|
protected final NumberFieldMapper mapper;
|
||||||
|
|
||||||
public CustomNumericField(NumberFieldMapper mapper, Number value, FieldType fieldType) {
|
public CustomNumericField(NumberFieldMapper mapper, Number value, MappedFieldType fieldType) {
|
||||||
super(mapper.names().indexName(), fieldType);
|
super(mapper.fieldType().names().indexName(), fieldType);
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
this.fieldsData = value;
|
this.fieldsData = value;
|
||||||
|
@ -431,13 +426,8 @@ public abstract class NumberFieldMapper extends AbstractFieldMapper implements A
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CustomLongNumericDocValuesField extends CustomNumericDocValuesField {
|
|
||||||
|
|
||||||
public static final FieldType TYPE = new FieldType();
|
public static class CustomLongNumericDocValuesField extends CustomNumericDocValuesField {
|
||||||
static {
|
|
||||||
TYPE.setDocValuesType(DocValuesType.BINARY);
|
|
||||||
TYPE.freeze();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final LongArrayList values;
|
private final LongArrayList values;
|
||||||
|
|
||||||
|
@ -481,9 +471,4 @@ public abstract class NumberFieldMapper extends AbstractFieldMapper implements A
|
||||||
builder.field("coerce", coerce.value());
|
builder.field("coerce", coerce.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isNumeric() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ package org.elasticsearch.index.mapper.core;
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.index.Terms;
|
import org.apache.lucene.index.Terms;
|
||||||
import org.apache.lucene.search.ConstantScoreQuery;
|
import org.apache.lucene.search.ConstantScoreQuery;
|
||||||
|
@ -43,13 +42,13 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
import org.elasticsearch.index.analysis.NumericIntegerAnalyzer;
|
import org.elasticsearch.index.analysis.NumericIntegerAnalyzer;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
import org.elasticsearch.index.mapper.MergeResult;
|
import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -69,7 +68,7 @@ public class ShortFieldMapper extends NumberFieldMapper {
|
||||||
public static final int DEFAULT_PRECISION_STEP = 8;
|
public static final int DEFAULT_PRECISION_STEP = 8;
|
||||||
|
|
||||||
public static class Defaults extends NumberFieldMapper.Defaults {
|
public static class Defaults extends NumberFieldMapper.Defaults {
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(NumberFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new ShortFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
|
@ -83,7 +82,7 @@ public class ShortFieldMapper extends NumberFieldMapper {
|
||||||
protected Short nullValue = Defaults.NULL_VALUE;
|
protected Short nullValue = Defaults.NULL_VALUE;
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE), DEFAULT_PRECISION_STEP);
|
super(name, Defaults.FIELD_TYPE, DEFAULT_PRECISION_STEP);
|
||||||
builder = this;
|
builder = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,13 +93,24 @@ public class ShortFieldMapper extends NumberFieldMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ShortFieldMapper build(BuilderContext context) {
|
public ShortFieldMapper build(BuilderContext context) {
|
||||||
fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
|
setupFieldType(context);
|
||||||
ShortFieldMapper fieldMapper = new ShortFieldMapper(buildNames(context), fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue,
|
ShortFieldMapper fieldMapper = new ShortFieldMapper(fieldType, docValues, nullValue,
|
||||||
ignoreMalformed(context), coerce(context), similarity, normsLoading, fieldDataSettings,
|
ignoreMalformed(context), coerce(context), fieldDataSettings,
|
||||||
context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
||||||
fieldMapper.includeInAll(includeInAll);
|
fieldMapper.includeInAll(includeInAll);
|
||||||
return fieldMapper;
|
return fieldMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NamedAnalyzer makeNumberAnalyzer(int precisionStep) {
|
||||||
|
String name = precisionStep == Integer.MAX_VALUE ? "_short/max" : ("_short/" + precisionStep);
|
||||||
|
return new NamedAnalyzer(name, new NumericIntegerAnalyzer(precisionStep));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int maxPrecisionStep() {
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TypeParser implements Mapper.TypeParser {
|
public static class TypeParser implements Mapper.TypeParser {
|
||||||
|
@ -124,23 +134,84 @@ public class ShortFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ShortFieldType extends NumberFieldType {
|
||||||
|
|
||||||
|
public ShortFieldType() {}
|
||||||
|
|
||||||
|
protected ShortFieldType(ShortFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NumberFieldType clone() {
|
||||||
|
return new ShortFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Short value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).shortValue();
|
||||||
|
}
|
||||||
|
if (value instanceof BytesRef) {
|
||||||
|
return Numbers.bytesToShort((BytesRef) value);
|
||||||
|
}
|
||||||
|
return Short.parseShort(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BytesRef indexedValueForSearch(Object value) {
|
||||||
|
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
||||||
|
NumericUtils.intToPrefixCoded(parseValue(value), 0, bytesRef); // 0 because of exact match
|
||||||
|
return bytesRef.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
||||||
|
return NumericRangeQuery.newIntRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
lowerTerm == null ? null : (int)parseValue(lowerTerm),
|
||||||
|
upperTerm == null ? null : (int)parseValue(upperTerm),
|
||||||
|
includeLower, includeUpper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
||||||
|
short iValue = Short.parseShort(value);
|
||||||
|
short iSim = fuzziness.asShort();
|
||||||
|
return NumericRangeQuery.newIntRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
iValue - iSim,
|
||||||
|
iValue + iSim,
|
||||||
|
true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
||||||
|
long minValue = NumericUtils.getMinInt(terms);
|
||||||
|
long maxValue = NumericUtils.getMaxInt(terms);
|
||||||
|
return new FieldStats.Long(
|
||||||
|
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), minValue, maxValue
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Short nullValue;
|
private Short nullValue;
|
||||||
|
|
||||||
private String nullValueAsString;
|
private String nullValueAsString;
|
||||||
|
|
||||||
protected ShortFieldMapper(Names names, int precisionStep, float boost, FieldType fieldType, Boolean docValues,
|
protected ShortFieldMapper(MappedFieldType fieldType, Boolean docValues,
|
||||||
Short nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
Short nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
||||||
SimilarityProvider similarity, Loading normsLoading, @Nullable Settings fieldDataSettings,
|
@Nullable Settings fieldDataSettings,
|
||||||
Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||||
super(names, precisionStep, boost, fieldType, docValues, ignoreMalformed, coerce, new NamedAnalyzer("_short/" + precisionStep,
|
super(fieldType, docValues, ignoreMalformed, coerce,
|
||||||
new NumericIntegerAnalyzer(precisionStep)), new NamedAnalyzer("_short/max", new NumericIntegerAnalyzer(Integer.MAX_VALUE)),
|
fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||||
similarity, normsLoading, fieldDataSettings, indexSettings, multiFields, copyTo);
|
|
||||||
this.nullValue = nullValue;
|
this.nullValue = nullValue;
|
||||||
this.nullValueAsString = nullValue == null ? null : nullValue.toString();
|
this.nullValueAsString = nullValue == null ? null : nullValue.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,33 +220,7 @@ public class ShortFieldMapper extends NumberFieldMapper {
|
||||||
return new FieldDataType("short");
|
return new FieldDataType("short");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private static short parseValue(Object value) {
|
||||||
protected int maxPrecisionStep() {
|
|
||||||
return 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Short value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (value instanceof Number) {
|
|
||||||
return ((Number) value).shortValue();
|
|
||||||
}
|
|
||||||
if (value instanceof BytesRef) {
|
|
||||||
return Numbers.bytesToShort((BytesRef) value);
|
|
||||||
}
|
|
||||||
return Short.parseShort(value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BytesRef indexedValueForSearch(Object value) {
|
|
||||||
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
|
||||||
NumericUtils.intToPrefixCoded(parseValue(value), 0, bytesRef); // 0 because of exact match
|
|
||||||
return bytesRef.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private short parseValue(Object value) {
|
|
||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
return ((Number) value).shortValue();
|
return ((Number) value).shortValue();
|
||||||
}
|
}
|
||||||
|
@ -185,28 +230,6 @@ public class ShortFieldMapper extends NumberFieldMapper {
|
||||||
return Short.parseShort(value.toString());
|
return Short.parseShort(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private int parseValueAsInt(Object value) {
|
|
||||||
return parseValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
|
||||||
short iValue = Short.parseShort(value);
|
|
||||||
short iSim = fuzziness.asShort();
|
|
||||||
return NumericRangeQuery.newIntRange(names.indexName(), precisionStep,
|
|
||||||
iValue - iSim,
|
|
||||||
iValue + iSim,
|
|
||||||
true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
|
||||||
return NumericRangeQuery.newIntRange(names.indexName(), precisionStep,
|
|
||||||
lowerTerm == null ? null : parseValueAsInt(lowerTerm),
|
|
||||||
upperTerm == null ? null : parseValueAsInt(upperTerm),
|
|
||||||
includeLower, includeUpper);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query nullValueFilter() {
|
public Query nullValueFilter() {
|
||||||
if (nullValue == null) {
|
if (nullValue == null) {
|
||||||
|
@ -223,7 +246,7 @@ public class ShortFieldMapper extends NumberFieldMapper {
|
||||||
@Override
|
@Override
|
||||||
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
||||||
short value;
|
short value;
|
||||||
float boost = this.boost;
|
float boost = this.fieldType.boost();
|
||||||
if (context.externalValueSet()) {
|
if (context.externalValueSet()) {
|
||||||
Object externalValue = context.externalValue();
|
Object externalValue = context.externalValue();
|
||||||
if (externalValue == null) {
|
if (externalValue == null) {
|
||||||
|
@ -245,7 +268,7 @@ public class ShortFieldMapper extends NumberFieldMapper {
|
||||||
value = ((Number) externalValue).shortValue();
|
value = ((Number) externalValue).shortValue();
|
||||||
}
|
}
|
||||||
if (context.includeInAll(includeInAll, this)) {
|
if (context.includeInAll(includeInAll, this)) {
|
||||||
context.allEntries().addText(names.fullName(), Short.toString(value), boost);
|
context.allEntries().addText(fieldType.names().fullName(), Short.toString(value), boost);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
XContentParser parser = context.parser();
|
XContentParser parser = context.parser();
|
||||||
|
@ -256,7 +279,7 @@ public class ShortFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
value = nullValue;
|
value = nullValue;
|
||||||
if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) {
|
if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) {
|
||||||
context.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
context.allEntries().addText(fieldType.names().fullName(), nullValueAsString, boost);
|
||||||
}
|
}
|
||||||
} else if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
|
} else if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
|
@ -285,16 +308,16 @@ public class ShortFieldMapper extends NumberFieldMapper {
|
||||||
} else {
|
} else {
|
||||||
value = parser.shortValue(coerce.value());
|
value = parser.shortValue(coerce.value());
|
||||||
if (context.includeInAll(includeInAll, this)) {
|
if (context.includeInAll(includeInAll, this)) {
|
||||||
context.allEntries().addText(names.fullName(), parser.text(), boost);
|
context.allEntries().addText(fieldType.names().fullName(), parser.text(), boost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
||||||
CustomShortNumericField field = new CustomShortNumericField(this, value, fieldType);
|
CustomShortNumericField field = new CustomShortNumericField(this, value, (NumberFieldType)fieldType);
|
||||||
field.setBoost(boost);
|
field.setBoost(boost);
|
||||||
fields.add(field);
|
fields.add(field);
|
||||||
}
|
}
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
addDocValue(context, fields, value);
|
addDocValue(context, fields, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,8 +343,8 @@ public class ShortFieldMapper extends NumberFieldMapper {
|
||||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||||
super.doXContentBody(builder, includeDefaults, params);
|
super.doXContentBody(builder, includeDefaults, params);
|
||||||
|
|
||||||
if (includeDefaults || precisionStep != DEFAULT_PRECISION_STEP) {
|
if (includeDefaults || fieldType.numericPrecisionStep() != DEFAULT_PRECISION_STEP) {
|
||||||
builder.field("precision_step", precisionStep);
|
builder.field("precision_step", fieldType.numericPrecisionStep());
|
||||||
}
|
}
|
||||||
if (includeDefaults || nullValue != null) {
|
if (includeDefaults || nullValue != null) {
|
||||||
builder.field("null_value", nullValue);
|
builder.field("null_value", nullValue);
|
||||||
|
@ -334,22 +357,13 @@ public class ShortFieldMapper extends NumberFieldMapper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public FieldStats stats(Terms terms, int maxDoc) throws IOException {
|
|
||||||
long minValue = NumericUtils.getMinInt(terms);
|
|
||||||
long maxValue = NumericUtils.getMaxInt(terms);
|
|
||||||
return new FieldStats.Long(
|
|
||||||
maxDoc, terms.getDocCount(), terms.getSumDocFreq(), terms.getSumTotalTermFreq(), minValue, maxValue
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CustomShortNumericField extends CustomNumericField {
|
public static class CustomShortNumericField extends CustomNumericField {
|
||||||
|
|
||||||
private final short number;
|
private final short number;
|
||||||
|
|
||||||
private final NumberFieldMapper mapper;
|
private final NumberFieldMapper mapper;
|
||||||
|
|
||||||
public CustomShortNumericField(NumberFieldMapper mapper, short number, FieldType fieldType) {
|
public CustomShortNumericField(NumberFieldMapper mapper, short number, NumberFieldType fieldType) {
|
||||||
super(mapper, number, fieldType);
|
super(mapper, number, fieldType);
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
this.number = number;
|
this.number = number;
|
||||||
|
|
|
@ -19,9 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.mapper.core;
|
package org.elasticsearch.index.mapper.core;
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.document.SortedSetDocValuesField;
|
import org.apache.lucene.document.SortedSetDocValuesField;
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
|
@ -34,19 +32,20 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
||||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
import org.elasticsearch.index.mapper.MergeResult;
|
import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.mapper.internal.AllFieldMapper;
|
import org.elasticsearch.index.mapper.internal.AllFieldMapper;
|
||||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.apache.lucene.index.IndexOptions.NONE;
|
||||||
import static org.elasticsearch.index.mapper.MapperBuilders.stringField;
|
import static org.elasticsearch.index.mapper.MapperBuilders.stringField;
|
||||||
import static org.elasticsearch.index.mapper.core.TypeParsers.parseField;
|
import static org.elasticsearch.index.mapper.core.TypeParsers.parseField;
|
||||||
import static org.elasticsearch.index.mapper.core.TypeParsers.parseMultiField;
|
import static org.elasticsearch.index.mapper.core.TypeParsers.parseMultiField;
|
||||||
|
@ -59,7 +58,7 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa
|
||||||
public static final String CONTENT_TYPE = "string";
|
public static final String CONTENT_TYPE = "string";
|
||||||
|
|
||||||
public static class Defaults extends AbstractFieldMapper.Defaults {
|
public static class Defaults extends AbstractFieldMapper.Defaults {
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new StringFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
|
@ -77,12 +76,10 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa
|
||||||
|
|
||||||
protected int positionOffsetGap = Defaults.POSITION_OFFSET_GAP;
|
protected int positionOffsetGap = Defaults.POSITION_OFFSET_GAP;
|
||||||
|
|
||||||
protected NamedAnalyzer searchQuotedAnalyzer;
|
|
||||||
|
|
||||||
protected int ignoreAbove = Defaults.IGNORE_ABOVE;
|
protected int ignoreAbove = Defaults.IGNORE_ABOVE;
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE));
|
super(name, Defaults.FIELD_TYPE);
|
||||||
builder = this;
|
builder = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,9 +91,6 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa
|
||||||
@Override
|
@Override
|
||||||
public Builder searchAnalyzer(NamedAnalyzer searchAnalyzer) {
|
public Builder searchAnalyzer(NamedAnalyzer searchAnalyzer) {
|
||||||
super.searchAnalyzer(searchAnalyzer);
|
super.searchAnalyzer(searchAnalyzer);
|
||||||
if (searchQuotedAnalyzer == null) {
|
|
||||||
searchQuotedAnalyzer = searchAnalyzer;
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +100,7 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder searchQuotedAnalyzer(NamedAnalyzer analyzer) {
|
public Builder searchQuotedAnalyzer(NamedAnalyzer analyzer) {
|
||||||
this.searchQuotedAnalyzer = analyzer;
|
this.fieldType.setSearchQuoteAnalyzer(analyzer);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,20 +112,20 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa
|
||||||
@Override
|
@Override
|
||||||
public StringFieldMapper build(BuilderContext context) {
|
public StringFieldMapper build(BuilderContext context) {
|
||||||
if (positionOffsetGap > 0) {
|
if (positionOffsetGap > 0) {
|
||||||
indexAnalyzer = new NamedAnalyzer(indexAnalyzer, positionOffsetGap);
|
fieldType.setIndexAnalyzer(new NamedAnalyzer(fieldType.indexAnalyzer(), positionOffsetGap));
|
||||||
searchAnalyzer = new NamedAnalyzer(searchAnalyzer, positionOffsetGap);
|
fieldType.setSearchAnalyzer(new NamedAnalyzer(fieldType.searchAnalyzer(), positionOffsetGap));
|
||||||
searchQuotedAnalyzer = new NamedAnalyzer(searchQuotedAnalyzer, positionOffsetGap);
|
fieldType.setSearchQuoteAnalyzer(new NamedAnalyzer(fieldType.searchQuoteAnalyzer(), positionOffsetGap));
|
||||||
}
|
}
|
||||||
// if the field is not analyzed, then by default, we should omit norms and have docs only
|
// if the field is not analyzed, then by default, we should omit norms and have docs only
|
||||||
// index options, as probably what the user really wants
|
// index options, as probably what the user really wants
|
||||||
// if they are set explicitly, we will use those values
|
// if they are set explicitly, we will use those values
|
||||||
// we also change the values on the default field type so that toXContent emits what
|
// we also change the values on the default field type so that toXContent emits what
|
||||||
// differs from the defaults
|
// differs from the defaults
|
||||||
FieldType defaultFieldType = new FieldType(Defaults.FIELD_TYPE);
|
MappedFieldType defaultFieldType = Defaults.FIELD_TYPE.clone();
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE && !fieldType.tokenized()) {
|
if (fieldType.indexOptions() != IndexOptions.NONE && !fieldType.tokenized()) {
|
||||||
defaultFieldType.setOmitNorms(true);
|
defaultFieldType.setOmitNorms(true);
|
||||||
defaultFieldType.setIndexOptions(IndexOptions.DOCS);
|
defaultFieldType.setIndexOptions(IndexOptions.DOCS);
|
||||||
if (!omitNormsSet && boost == Defaults.BOOST) {
|
if (!omitNormsSet && fieldType.boost() == Defaults.BOOST) {
|
||||||
fieldType.setOmitNorms(true);
|
fieldType.setOmitNorms(true);
|
||||||
}
|
}
|
||||||
if (!indexOptionsSet) {
|
if (!indexOptionsSet) {
|
||||||
|
@ -139,9 +133,9 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defaultFieldType.freeze();
|
defaultFieldType.freeze();
|
||||||
StringFieldMapper fieldMapper = new StringFieldMapper(buildNames(context),
|
setupFieldType(context);
|
||||||
boost, fieldType, defaultFieldType, docValues, nullValue, indexAnalyzer, searchAnalyzer, searchQuotedAnalyzer,
|
StringFieldMapper fieldMapper = new StringFieldMapper(
|
||||||
positionOffsetGap, ignoreAbove, similarity, normsLoading,
|
fieldType, defaultFieldType, docValues, nullValue, positionOffsetGap, ignoreAbove,
|
||||||
fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
||||||
fieldMapper.includeInAll(includeInAll);
|
fieldMapper.includeInAll(includeInAll);
|
||||||
return fieldMapper;
|
return fieldMapper;
|
||||||
|
@ -174,14 +168,14 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa
|
||||||
builder.positionOffsetGap(XContentMapValues.nodeIntegerValue(propNode, -1));
|
builder.positionOffsetGap(XContentMapValues.nodeIntegerValue(propNode, -1));
|
||||||
// we need to update to actual analyzers if they are not set in this case...
|
// we need to update to actual analyzers if they are not set in this case...
|
||||||
// so we can inject the position offset gap...
|
// so we can inject the position offset gap...
|
||||||
if (builder.indexAnalyzer == null) {
|
if (builder.fieldType.indexAnalyzer() == null) {
|
||||||
builder.indexAnalyzer = parserContext.analysisService().defaultIndexAnalyzer();
|
builder.fieldType.setIndexAnalyzer(parserContext.analysisService().defaultIndexAnalyzer());
|
||||||
}
|
}
|
||||||
if (builder.searchAnalyzer == null) {
|
if (builder.fieldType.searchAnalyzer() == null) {
|
||||||
builder.searchAnalyzer = parserContext.analysisService().defaultSearchAnalyzer();
|
builder.fieldType.setSearchAnalyzer(parserContext.analysisService().defaultSearchAnalyzer());
|
||||||
}
|
}
|
||||||
if (builder.searchQuotedAnalyzer == null) {
|
if (builder.fieldType.searchQuoteAnalyzer() == null) {
|
||||||
builder.searchQuotedAnalyzer = parserContext.analysisService().defaultSearchQuoteAnalyzer();
|
builder.fieldType.setSearchQuoteAnalyzer(parserContext.analysisService().defaultSearchQuoteAnalyzer());
|
||||||
}
|
}
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
} else if (propName.equals("ignore_above")) {
|
} else if (propName.equals("ignore_above")) {
|
||||||
|
@ -195,32 +189,50 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class StringFieldType extends MappedFieldType {
|
||||||
|
|
||||||
|
public StringFieldType() {
|
||||||
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected StringFieldType(StringFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringFieldType clone() {
|
||||||
|
return new StringFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String nullValue;
|
private String nullValue;
|
||||||
private Boolean includeInAll;
|
private Boolean includeInAll;
|
||||||
private int positionOffsetGap;
|
private int positionOffsetGap;
|
||||||
private NamedAnalyzer searchQuotedAnalyzer;
|
|
||||||
private int ignoreAbove;
|
private int ignoreAbove;
|
||||||
private final FieldType defaultFieldType;
|
private final MappedFieldType defaultFieldType;
|
||||||
|
|
||||||
protected StringFieldMapper(Names names, float boost, FieldType fieldType, FieldType defaultFieldType, Boolean docValues,
|
protected StringFieldMapper(MappedFieldType fieldType, MappedFieldType defaultFieldType, Boolean docValues,
|
||||||
String nullValue, NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer,
|
String nullValue, int positionOffsetGap, int ignoreAbove, @Nullable Settings fieldDataSettings,
|
||||||
NamedAnalyzer searchQuotedAnalyzer, int positionOffsetGap, int ignoreAbove,
|
|
||||||
SimilarityProvider similarity, Loading normsLoading, @Nullable Settings fieldDataSettings,
|
|
||||||
Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||||
super(names, boost, fieldType, docValues, indexAnalyzer, searchAnalyzer,
|
super(fieldType, docValues, fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||||
similarity, normsLoading, fieldDataSettings, indexSettings, multiFields, copyTo);
|
if (fieldType.tokenized() && fieldType.indexOptions() != NONE && fieldType().hasDocValues()) {
|
||||||
if (fieldType.tokenized() && fieldType.indexOptions() != IndexOptions.NONE && hasDocValues()) {
|
throw new MapperParsingException("Field [" + fieldType.names().fullName() + "] cannot be analyzed and have doc values");
|
||||||
throw new MapperParsingException("Field [" + names.fullName() + "] cannot be analyzed and have doc values");
|
|
||||||
}
|
}
|
||||||
this.defaultFieldType = defaultFieldType;
|
this.defaultFieldType = defaultFieldType;
|
||||||
this.nullValue = nullValue;
|
this.nullValue = nullValue;
|
||||||
this.positionOffsetGap = positionOffsetGap;
|
this.positionOffsetGap = positionOffsetGap;
|
||||||
this.searchQuotedAnalyzer = searchQuotedAnalyzer != null ? searchQuotedAnalyzer : this.searchAnalyzer;
|
|
||||||
this.ignoreAbove = ignoreAbove;
|
this.ignoreAbove = ignoreAbove;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return defaultFieldType;
|
return defaultFieldType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,14 +260,6 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa
|
||||||
includeInAll = null;
|
includeInAll = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean customBoost() {
|
protected boolean customBoost() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -269,11 +273,6 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa
|
||||||
return ignoreAbove;
|
return ignoreAbove;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Analyzer searchQuoteAnalyzer() {
|
|
||||||
return this.searchQuotedAnalyzer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query nullValueFilter() {
|
public Query nullValueFilter() {
|
||||||
if (nullValue == null) {
|
if (nullValue == null) {
|
||||||
|
@ -284,7 +283,7 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void parseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
protected void parseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
||||||
ValueAndBoost valueAndBoost = parseCreateFieldForString(context, nullValue, boost);
|
ValueAndBoost valueAndBoost = parseCreateFieldForString(context, nullValue, fieldType.boost());
|
||||||
if (valueAndBoost.value() == null) {
|
if (valueAndBoost.value() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -292,19 +291,19 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (context.includeInAll(includeInAll, this)) {
|
if (context.includeInAll(includeInAll, this)) {
|
||||||
context.allEntries().addText(names.fullName(), valueAndBoost.value(), valueAndBoost.boost());
|
context.allEntries().addText(fieldType.names().fullName(), valueAndBoost.value(), valueAndBoost.boost());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
||||||
Field field = new Field(names.indexName(), valueAndBoost.value(), fieldType);
|
Field field = new Field(fieldType.names().indexName(), valueAndBoost.value(), fieldType);
|
||||||
field.setBoost(valueAndBoost.boost());
|
field.setBoost(valueAndBoost.boost());
|
||||||
fields.add(field);
|
fields.add(field);
|
||||||
}
|
}
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
fields.add(new SortedSetDocValuesField(names.indexName(), new BytesRef(valueAndBoost.value())));
|
fields.add(new SortedSetDocValuesField(fieldType.names().indexName(), new BytesRef(valueAndBoost.value())));
|
||||||
}
|
}
|
||||||
if (fields.isEmpty()) {
|
if (fields.isEmpty()) {
|
||||||
context.ignoredValue(names.indexName(), valueAndBoost.value());
|
context.ignoredValue(fieldType.names().indexName(), valueAndBoost.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,13 +380,14 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa
|
||||||
if (includeDefaults || positionOffsetGap != Defaults.POSITION_OFFSET_GAP) {
|
if (includeDefaults || positionOffsetGap != Defaults.POSITION_OFFSET_GAP) {
|
||||||
builder.field("position_offset_gap", positionOffsetGap);
|
builder.field("position_offset_gap", positionOffsetGap);
|
||||||
}
|
}
|
||||||
if (searchQuotedAnalyzer != null && !searchQuotedAnalyzer.name().equals(searchAnalyzer.name())) {
|
NamedAnalyzer searchQuoteAnalyzer = fieldType.searchQuoteAnalyzer();
|
||||||
builder.field("search_quote_analyzer", searchQuotedAnalyzer.name());
|
if (searchQuoteAnalyzer != null && !searchQuoteAnalyzer.name().equals(fieldType.searchAnalyzer().name())) {
|
||||||
|
builder.field("search_quote_analyzer", searchQuoteAnalyzer.name());
|
||||||
} else if (includeDefaults) {
|
} else if (includeDefaults) {
|
||||||
if (searchQuotedAnalyzer == null) {
|
if (searchQuoteAnalyzer == null) {
|
||||||
builder.field("search_quote_analyzer", "default");
|
builder.field("search_quote_analyzer", "default");
|
||||||
} else {
|
} else {
|
||||||
builder.field("search_quote_analyzer", searchQuotedAnalyzer.name());
|
builder.field("search_quote_analyzer", searchQuoteAnalyzer.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (includeDefaults || ignoreAbove != Defaults.IGNORE_ABOVE) {
|
if (includeDefaults || ignoreAbove != Defaults.IGNORE_ABOVE) {
|
||||||
|
|
|
@ -22,18 +22,18 @@ package org.elasticsearch.index.mapper.core;
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
|
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
|
||||||
import org.elasticsearch.common.Explicit;
|
import org.elasticsearch.common.Explicit;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
|
import org.elasticsearch.index.analysis.NumericIntegerAnalyzer;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeResult;
|
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.mapper.core.StringFieldMapper.ValueAndBoost;
|
import org.elasticsearch.index.mapper.core.StringFieldMapper.ValueAndBoost;
|
||||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
import org.elasticsearch.index.similarity.SimilarityProvider;
|
||||||
|
@ -43,6 +43,7 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.apache.lucene.index.IndexOptions.NONE;
|
||||||
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeIntegerValue;
|
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeIntegerValue;
|
||||||
import static org.elasticsearch.index.mapper.MapperBuilders.tokenCountField;
|
import static org.elasticsearch.index.mapper.MapperBuilders.tokenCountField;
|
||||||
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
|
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
|
||||||
|
@ -55,6 +56,7 @@ public class TokenCountFieldMapper extends IntegerFieldMapper {
|
||||||
public static final String CONTENT_TYPE = "token_count";
|
public static final String CONTENT_TYPE = "token_count";
|
||||||
|
|
||||||
public static class Defaults extends IntegerFieldMapper.Defaults {
|
public static class Defaults extends IntegerFieldMapper.Defaults {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder extends NumberFieldMapper.Builder<Builder, TokenCountFieldMapper> {
|
public static class Builder extends NumberFieldMapper.Builder<Builder, TokenCountFieldMapper> {
|
||||||
|
@ -62,7 +64,7 @@ public class TokenCountFieldMapper extends IntegerFieldMapper {
|
||||||
private NamedAnalyzer analyzer;
|
private NamedAnalyzer analyzer;
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_32_BIT);
|
super(name, Defaults.FIELD_TYPE, Defaults.PRECISION_STEP_32_BIT);
|
||||||
builder = this;
|
builder = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,13 +84,23 @@ public class TokenCountFieldMapper extends IntegerFieldMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TokenCountFieldMapper build(BuilderContext context) {
|
public TokenCountFieldMapper build(BuilderContext context) {
|
||||||
fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
|
setupFieldType(context);
|
||||||
TokenCountFieldMapper fieldMapper = new TokenCountFieldMapper(buildNames(context), fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue,
|
TokenCountFieldMapper fieldMapper = new TokenCountFieldMapper(fieldType, docValues, nullValue,
|
||||||
ignoreMalformed(context), coerce(context), similarity, normsLoading, fieldDataSettings, context.indexSettings(),
|
ignoreMalformed(context), coerce(context), fieldDataSettings, context.indexSettings(),
|
||||||
analyzer, multiFieldsBuilder.build(this, context), copyTo);
|
analyzer, multiFieldsBuilder.build(this, context), copyTo);
|
||||||
fieldMapper.includeInAll(includeInAll);
|
fieldMapper.includeInAll(includeInAll);
|
||||||
return fieldMapper;
|
return fieldMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NamedAnalyzer makeNumberAnalyzer(int precisionStep) {
|
||||||
|
return NumericIntegerAnalyzer.buildNamedAnalyzer(precisionStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int maxPrecisionStep() {
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TypeParser implements Mapper.TypeParser {
|
public static class TypeParser implements Mapper.TypeParser {
|
||||||
|
@ -122,34 +134,33 @@ public class TokenCountFieldMapper extends IntegerFieldMapper {
|
||||||
|
|
||||||
private NamedAnalyzer analyzer;
|
private NamedAnalyzer analyzer;
|
||||||
|
|
||||||
protected TokenCountFieldMapper(Names names, int precisionStep, float boost, FieldType fieldType, Boolean docValues, Integer nullValue,
|
protected TokenCountFieldMapper(MappedFieldType fieldType, Boolean docValues, Integer nullValue,
|
||||||
Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce, Settings fieldDataSettings, Settings indexSettings, NamedAnalyzer analyzer,
|
||||||
SimilarityProvider similarity, Loading normsLoading, Settings fieldDataSettings, Settings indexSettings, NamedAnalyzer analyzer,
|
|
||||||
MultiFields multiFields, CopyTo copyTo) {
|
MultiFields multiFields, CopyTo copyTo) {
|
||||||
super(names, precisionStep, boost, fieldType, docValues, nullValue, ignoreMalformed, coerce,
|
super(fieldType, docValues, nullValue, ignoreMalformed, coerce,
|
||||||
similarity, normsLoading, fieldDataSettings, indexSettings, multiFields, copyTo);
|
fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||||
|
|
||||||
this.analyzer = analyzer;
|
this.analyzer = analyzer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void parseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
protected void parseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
||||||
ValueAndBoost valueAndBoost = StringFieldMapper.parseCreateFieldForString(context, null /* Out null value is an int so we convert*/, boost);
|
ValueAndBoost valueAndBoost = StringFieldMapper.parseCreateFieldForString(context, null /* Out null value is an int so we convert*/, fieldType.boost());
|
||||||
if (valueAndBoost.value() == null && nullValue() == null) {
|
if (valueAndBoost.value() == null && nullValue() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored() || hasDocValues()) {
|
if (fieldType.indexOptions() != NONE || fieldType.stored() || fieldType().hasDocValues()) {
|
||||||
int count;
|
int count;
|
||||||
if (valueAndBoost.value() == null) {
|
if (valueAndBoost.value() == null) {
|
||||||
count = nullValue();
|
count = nullValue();
|
||||||
} else {
|
} else {
|
||||||
count = countPositions(analyzer.analyzer().tokenStream(names().shortName(), valueAndBoost.value()));
|
count = countPositions(analyzer.analyzer().tokenStream(fieldType().names().shortName(), valueAndBoost.value()));
|
||||||
}
|
}
|
||||||
addIntegerFields(context, fields, count, valueAndBoost.boost());
|
addIntegerFields(context, fields, count, valueAndBoost.boost());
|
||||||
}
|
}
|
||||||
if (fields.isEmpty()) {
|
if (fields.isEmpty()) {
|
||||||
context.ignoredValue(names.indexName(), valueAndBoost.value());
|
context.ignoredValue(fieldType.names().indexName(), valueAndBoost.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ import org.elasticsearch.common.settings.loader.SettingsLoader;
|
||||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
import org.elasticsearch.index.mapper.ContentPath;
|
import org.elasticsearch.index.mapper.ContentPath;
|
||||||
import org.elasticsearch.index.mapper.DocumentMapperParser;
|
import org.elasticsearch.index.mapper.DocumentMapperParser;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper.Loading;
|
import org.elasticsearch.index.mapper.MappedFieldType.Loading;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.object.ObjectMapper;
|
import org.elasticsearch.index.mapper.object.ObjectMapper;
|
||||||
|
|
|
@ -24,10 +24,9 @@ import com.carrotsearch.hppc.cursors.ObjectCursor;
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.collect.Iterators;
|
import com.google.common.collect.Iterators;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.DocValuesType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
|
import org.apache.lucene.util.NumericUtils;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
|
@ -41,10 +40,9 @@ import org.elasticsearch.common.util.ByteUtils;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
||||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
import org.elasticsearch.index.mapper.ContentPath;
|
import org.elasticsearch.index.mapper.ContentPath;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -56,7 +54,6 @@ import org.elasticsearch.index.mapper.core.NumberFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.core.NumberFieldMapper.CustomNumericDocValuesField;
|
import org.elasticsearch.index.mapper.core.NumberFieldMapper.CustomNumericDocValuesField;
|
||||||
import org.elasticsearch.index.mapper.core.StringFieldMapper;
|
import org.elasticsearch.index.mapper.core.StringFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.object.ArrayValueMapperParser;
|
import org.elasticsearch.index.mapper.object.ArrayValueMapperParser;
|
||||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -97,7 +94,6 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
|
|
||||||
public static class Defaults {
|
public static class Defaults {
|
||||||
public static final ContentPath.Type PATH_TYPE = ContentPath.Type.FULL;
|
public static final ContentPath.Type PATH_TYPE = ContentPath.Type.FULL;
|
||||||
public static final boolean STORE = false;
|
|
||||||
public static final boolean ENABLE_LATLON = false;
|
public static final boolean ENABLE_LATLON = false;
|
||||||
public static final boolean ENABLE_GEOHASH = false;
|
public static final boolean ENABLE_GEOHASH = false;
|
||||||
public static final boolean ENABLE_GEOHASH_PREFIX = false;
|
public static final boolean ENABLE_GEOHASH_PREFIX = false;
|
||||||
|
@ -107,7 +103,7 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
public static final boolean VALIDATE_LAT = true;
|
public static final boolean VALIDATE_LAT = true;
|
||||||
public static final boolean VALIDATE_LON = true;
|
public static final boolean VALIDATE_LON = true;
|
||||||
|
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(StringFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new GeoPointFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
||||||
|
@ -131,16 +127,15 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
|
|
||||||
private int geoHashPrecision = Defaults.GEO_HASH_PRECISION;
|
private int geoHashPrecision = Defaults.GEO_HASH_PRECISION;
|
||||||
|
|
||||||
boolean validateLat = Defaults.VALIDATE_LAT;
|
|
||||||
boolean validateLon = Defaults.VALIDATE_LON;
|
|
||||||
boolean normalizeLat = Defaults.NORMALIZE_LAT;
|
|
||||||
boolean normalizeLon = Defaults.NORMALIZE_LON;
|
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE));
|
super(name, Defaults.FIELD_TYPE);
|
||||||
this.builder = this;
|
this.builder = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GeoPointFieldType fieldType() {
|
||||||
|
return (GeoPointFieldType)fieldType;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Builder multiFieldPathType(ContentPath.Type pathType) {
|
public Builder multiFieldPathType(ContentPath.Type pathType) {
|
||||||
this.pathType = pathType;
|
this.pathType = pathType;
|
||||||
|
@ -185,6 +180,7 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
|
|
||||||
DoubleFieldMapper latMapper = null;
|
DoubleFieldMapper latMapper = null;
|
||||||
DoubleFieldMapper lonMapper = null;
|
DoubleFieldMapper lonMapper = null;
|
||||||
|
GeoPointFieldType geoPointFieldType = (GeoPointFieldType)fieldType;
|
||||||
|
|
||||||
context.path().add(name);
|
context.path().add(name);
|
||||||
if (enableLatLon) {
|
if (enableLatLon) {
|
||||||
|
@ -196,10 +192,13 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
}
|
}
|
||||||
latMapper = (DoubleFieldMapper) latMapperBuilder.includeInAll(false).store(fieldType.stored()).docValues(false).build(context);
|
latMapper = (DoubleFieldMapper) latMapperBuilder.includeInAll(false).store(fieldType.stored()).docValues(false).build(context);
|
||||||
lonMapper = (DoubleFieldMapper) lonMapperBuilder.includeInAll(false).store(fieldType.stored()).docValues(false).build(context);
|
lonMapper = (DoubleFieldMapper) lonMapperBuilder.includeInAll(false).store(fieldType.stored()).docValues(false).build(context);
|
||||||
|
geoPointFieldType.setLatLonEnabled(latMapper.fieldType(), lonMapper.fieldType());
|
||||||
}
|
}
|
||||||
StringFieldMapper geohashMapper = null;
|
StringFieldMapper geohashMapper = null;
|
||||||
if (enableGeoHash) {
|
if (enableGeoHash || enableGeohashPrefix) {
|
||||||
|
// TODO: possible also implicitly enable geohash if geohash precision is set
|
||||||
geohashMapper = stringField(Names.GEOHASH).index(true).tokenized(false).includeInAll(false).omitNorms(true).indexOptions(IndexOptions.DOCS).build(context);
|
geohashMapper = stringField(Names.GEOHASH).index(true).tokenized(false).includeInAll(false).omitNorms(true).indexOptions(IndexOptions.DOCS).build(context);
|
||||||
|
geoPointFieldType.setGeohashEnabled(geohashMapper.fieldType(), geoHashPrecision, enableGeohashPrefix);
|
||||||
}
|
}
|
||||||
context.path().remove();
|
context.path().remove();
|
||||||
|
|
||||||
|
@ -208,11 +207,11 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
// this is important: even if geo points feel like they need to be tokenized to distinguish lat from lon, we actually want to
|
// this is important: even if geo points feel like they need to be tokenized to distinguish lat from lon, we actually want to
|
||||||
// store them as a single token.
|
// store them as a single token.
|
||||||
fieldType.setTokenized(false);
|
fieldType.setTokenized(false);
|
||||||
|
fieldType.setHasDocValues(false);
|
||||||
|
setupFieldType(context);
|
||||||
|
|
||||||
return new GeoPointFieldMapper(buildNames(context), fieldType, docValues, indexAnalyzer, searchAnalyzer,
|
return new GeoPointFieldMapper(fieldType, docValues, fieldDataSettings, context.indexSettings(), origPathType,
|
||||||
similarity, fieldDataSettings, context.indexSettings(), origPathType, enableLatLon, enableGeoHash, enableGeohashPrefix, precisionStep,
|
latMapper, lonMapper, geohashMapper, multiFieldsBuilder.build(this, context));
|
||||||
geoHashPrecision, latMapper, lonMapper, geohashMapper, validateLon, validateLat, normalizeLon, normalizeLat
|
|
||||||
, multiFieldsBuilder.build(this, context));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,24 +250,24 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
}
|
}
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
} else if (fieldName.equals("validate")) {
|
} else if (fieldName.equals("validate")) {
|
||||||
builder.validateLat = XContentMapValues.nodeBooleanValue(fieldNode);
|
builder.fieldType().setValidateLat(XContentMapValues.nodeBooleanValue(fieldNode));
|
||||||
builder.validateLon = XContentMapValues.nodeBooleanValue(fieldNode);
|
builder.fieldType().setValidateLon(XContentMapValues.nodeBooleanValue(fieldNode));
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
} else if (fieldName.equals("validate_lon")) {
|
} else if (fieldName.equals("validate_lon")) {
|
||||||
builder.validateLon = XContentMapValues.nodeBooleanValue(fieldNode);
|
builder.fieldType().setValidateLon(XContentMapValues.nodeBooleanValue(fieldNode));
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
} else if (fieldName.equals("validate_lat")) {
|
} else if (fieldName.equals("validate_lat")) {
|
||||||
builder.validateLat = XContentMapValues.nodeBooleanValue(fieldNode);
|
builder.fieldType().setValidateLat(XContentMapValues.nodeBooleanValue(fieldNode));
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
} else if (fieldName.equals("normalize")) {
|
} else if (fieldName.equals("normalize")) {
|
||||||
builder.normalizeLat = XContentMapValues.nodeBooleanValue(fieldNode);
|
builder.fieldType().setNormalizeLat(XContentMapValues.nodeBooleanValue(fieldNode));
|
||||||
builder.normalizeLon = XContentMapValues.nodeBooleanValue(fieldNode);
|
builder.fieldType().setNormalizeLon(XContentMapValues.nodeBooleanValue(fieldNode));
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
} else if (fieldName.equals("normalize_lat")) {
|
} else if (fieldName.equals("normalize_lat")) {
|
||||||
builder.normalizeLat = XContentMapValues.nodeBooleanValue(fieldNode);
|
builder.fieldType().setNormalizeLat(XContentMapValues.nodeBooleanValue(fieldNode));
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
} else if (fieldName.equals("normalize_lon")) {
|
} else if (fieldName.equals("normalize_lon")) {
|
||||||
builder.normalizeLon = XContentMapValues.nodeBooleanValue(fieldNode);
|
builder.fieldType().setNormalizeLon(XContentMapValues.nodeBooleanValue(fieldNode));
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
} else if (parseMultiField(builder, name, parserContext, fieldName, fieldNode)) {
|
} else if (parseMultiField(builder, name, parserContext, fieldName, fieldNode)) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
|
@ -278,6 +277,128 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class GeoPointFieldType extends MappedFieldType {
|
||||||
|
|
||||||
|
private MappedFieldType geohashFieldType;
|
||||||
|
private int geohashPrecision;
|
||||||
|
private boolean geohashPrefixEnabled;
|
||||||
|
|
||||||
|
private MappedFieldType latFieldType;
|
||||||
|
private MappedFieldType lonFieldType;
|
||||||
|
private boolean validateLon = true;
|
||||||
|
private boolean validateLat = true;
|
||||||
|
private boolean normalizeLon = true;
|
||||||
|
private boolean normalizeLat = true;
|
||||||
|
|
||||||
|
public GeoPointFieldType() {
|
||||||
|
super(StringFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected GeoPointFieldType(GeoPointFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
this.geohashFieldType = ref.geohashFieldType; // copying ref is ok, this can never be modified
|
||||||
|
this.geohashPrecision = ref.geohashPrecision;
|
||||||
|
this.geohashPrefixEnabled = ref.geohashPrefixEnabled;
|
||||||
|
this.latFieldType = ref.latFieldType; // copying ref is ok, this can never be modified
|
||||||
|
this.lonFieldType = ref.lonFieldType; // copying ref is ok, this can never be modified
|
||||||
|
this.validateLon = ref.validateLon;
|
||||||
|
this.validateLat = ref.validateLat;
|
||||||
|
this.normalizeLon = ref.normalizeLon;
|
||||||
|
this.normalizeLat = ref.normalizeLat;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new GeoPointFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGeohashEnabled() {
|
||||||
|
return geohashFieldType != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MappedFieldType geohashFieldType() {
|
||||||
|
return geohashFieldType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int geohashPrecision() {
|
||||||
|
return geohashPrecision;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGeohashPrefixEnabled() {
|
||||||
|
return geohashPrefixEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGeohashEnabled(MappedFieldType geohashFieldType, int geohashPrecision, boolean geohashPrefixEnabled) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.geohashFieldType = geohashFieldType;
|
||||||
|
this.geohashPrecision = geohashPrecision;
|
||||||
|
this.geohashPrefixEnabled = geohashPrefixEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLatLonEnabled() {
|
||||||
|
return latFieldType != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MappedFieldType latFieldType() {
|
||||||
|
return latFieldType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MappedFieldType lonFieldType() {
|
||||||
|
return lonFieldType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLatLonEnabled(MappedFieldType latFieldType, MappedFieldType lonFieldType) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.latFieldType = latFieldType;
|
||||||
|
this.lonFieldType = lonFieldType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean validateLon() {
|
||||||
|
return validateLon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValidateLon(boolean validateLon) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.validateLon = validateLon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean validateLat() {
|
||||||
|
return validateLat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValidateLat(boolean validateLat) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.validateLat = validateLat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean normalizeLon() {
|
||||||
|
return normalizeLon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNormalizeLon(boolean normalizeLon) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.normalizeLon = normalizeLon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean normalizeLat() {
|
||||||
|
return normalizeLat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNormalizeLat(boolean normalizeLat) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.normalizeLat = normalizeLat;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GeoPoint value(Object value) {
|
||||||
|
if (value instanceof GeoPoint) {
|
||||||
|
return (GeoPoint) value;
|
||||||
|
} else {
|
||||||
|
return GeoPoint.parseFromLatLon(value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A byte-aligned fixed-length encoding for latitudes and longitudes.
|
* A byte-aligned fixed-length encoding for latitudes and longitudes.
|
||||||
*/
|
*/
|
||||||
|
@ -405,52 +526,19 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
|
|
||||||
private final ContentPath.Type pathType;
|
private final ContentPath.Type pathType;
|
||||||
|
|
||||||
private final boolean enableLatLon;
|
|
||||||
|
|
||||||
private final boolean enableGeoHash;
|
|
||||||
|
|
||||||
private final boolean enableGeohashPrefix;
|
|
||||||
|
|
||||||
private final Integer precisionStep;
|
|
||||||
|
|
||||||
private final int geoHashPrecision;
|
|
||||||
|
|
||||||
private final DoubleFieldMapper latMapper;
|
private final DoubleFieldMapper latMapper;
|
||||||
|
|
||||||
private final DoubleFieldMapper lonMapper;
|
private final DoubleFieldMapper lonMapper;
|
||||||
|
|
||||||
private final StringFieldMapper geohashMapper;
|
private final StringFieldMapper geohashMapper;
|
||||||
|
|
||||||
private boolean validateLon;
|
public GeoPointFieldMapper(MappedFieldType fieldType, Boolean docValues, @Nullable Settings fieldDataSettings, Settings indexSettings,
|
||||||
private boolean validateLat;
|
ContentPath.Type pathType, DoubleFieldMapper latMapper, DoubleFieldMapper lonMapper, StringFieldMapper geohashMapper,MultiFields multiFields) {
|
||||||
|
super(fieldType, docValues, fieldDataSettings, indexSettings, multiFields, null);
|
||||||
private final boolean normalizeLon;
|
|
||||||
private final boolean normalizeLat;
|
|
||||||
|
|
||||||
public GeoPointFieldMapper(FieldMapper.Names names, FieldType fieldType, Boolean docValues,
|
|
||||||
NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer,
|
|
||||||
SimilarityProvider similarity, @Nullable Settings fieldDataSettings, Settings indexSettings,
|
|
||||||
ContentPath.Type pathType, boolean enableLatLon, boolean enableGeoHash, boolean enableGeohashPrefix, Integer precisionStep, int geoHashPrecision,
|
|
||||||
DoubleFieldMapper latMapper, DoubleFieldMapper lonMapper, StringFieldMapper geohashMapper,
|
|
||||||
boolean validateLon, boolean validateLat,
|
|
||||||
boolean normalizeLon, boolean normalizeLat, MultiFields multiFields) {
|
|
||||||
super(names, 1f, fieldType, docValues, null, indexAnalyzer, similarity, null, fieldDataSettings, indexSettings, multiFields, null);
|
|
||||||
this.pathType = pathType;
|
this.pathType = pathType;
|
||||||
this.enableLatLon = enableLatLon;
|
|
||||||
this.enableGeoHash = enableGeoHash || enableGeohashPrefix; // implicitly enable geohashes if geohash_prefix is set
|
|
||||||
this.enableGeohashPrefix = enableGeohashPrefix;
|
|
||||||
this.precisionStep = precisionStep;
|
|
||||||
this.geoHashPrecision = geoHashPrecision;
|
|
||||||
|
|
||||||
this.latMapper = latMapper;
|
this.latMapper = latMapper;
|
||||||
this.lonMapper = lonMapper;
|
this.lonMapper = lonMapper;
|
||||||
this.geohashMapper = geohashMapper;
|
this.geohashMapper = geohashMapper;
|
||||||
|
|
||||||
this.validateLat = validateLat;
|
|
||||||
this.validateLon = validateLon;
|
|
||||||
|
|
||||||
this.normalizeLat = normalizeLat;
|
|
||||||
this.normalizeLon = normalizeLon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -459,7 +547,12 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public GeoPointFieldType fieldType() {
|
||||||
|
return (GeoPointFieldType)fieldType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,39 +566,6 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DoubleFieldMapper latMapper() {
|
|
||||||
return latMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DoubleFieldMapper lonMapper() {
|
|
||||||
return lonMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StringFieldMapper geoHashStringMapper() {
|
|
||||||
return this.geohashMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
int geoHashPrecision() {
|
|
||||||
return geoHashPrecision;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEnableLatLon() {
|
|
||||||
return enableLatLon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEnableGeohashPrefix() {
|
|
||||||
return enableGeohashPrefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GeoPoint value(Object value) {
|
|
||||||
if (value instanceof GeoPoint) {
|
|
||||||
return (GeoPoint) value;
|
|
||||||
} else {
|
|
||||||
return GeoPoint.parseFromLatLon(value.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void parseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
protected void parseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
||||||
throw new UnsupportedOperationException("Parsing is implemented in parse(), this method should NEVER be called");
|
throw new UnsupportedOperationException("Parsing is implemented in parse(), this method should NEVER be called");
|
||||||
|
@ -515,7 +575,7 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
public Mapper parse(ParseContext context) throws IOException {
|
public Mapper parse(ParseContext context) throws IOException {
|
||||||
ContentPath.Type origPathType = context.path().pathType();
|
ContentPath.Type origPathType = context.path().pathType();
|
||||||
context.path().pathType(pathType);
|
context.path().pathType(pathType);
|
||||||
context.path().add(names().shortName());
|
context.path().add(fieldType().names().shortName());
|
||||||
|
|
||||||
GeoPoint sparse = context.parseExternalValue(GeoPoint.class);
|
GeoPoint sparse = context.parseExternalValue(GeoPoint.class);
|
||||||
|
|
||||||
|
@ -565,9 +625,9 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseGeohashField(ParseContext context, String geohash) throws IOException {
|
private void addGeohashField(ParseContext context, String geohash) throws IOException {
|
||||||
int len = Math.min(geoHashPrecision, geohash.length());
|
int len = Math.min(fieldType().geohashPrecision(), geohash.length());
|
||||||
int min = enableGeohashPrefix ? 1 : geohash.length();
|
int min = fieldType().isGeohashPrefixEnabled() ? 1 : geohash.length();
|
||||||
|
|
||||||
for (int i = len; i >= min; i--) {
|
for (int i = len; i >= min; i--) {
|
||||||
// side effect of this call is adding the field
|
// side effect of this call is adding the field
|
||||||
|
@ -584,40 +644,40 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parse(ParseContext context, GeoPoint point, String geohash) throws IOException {
|
private void parse(ParseContext context, GeoPoint point, String geohash) throws IOException {
|
||||||
if (normalizeLat || normalizeLon) {
|
if (fieldType().normalizeLat() || fieldType().normalizeLon()) {
|
||||||
GeoUtils.normalizePoint(point, normalizeLat, normalizeLon);
|
GeoUtils.normalizePoint(point, fieldType().normalizeLat(), fieldType().normalizeLon());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (validateLat) {
|
if (fieldType().validateLat()) {
|
||||||
if (point.lat() > 90.0 || point.lat() < -90.0) {
|
if (point.lat() > 90.0 || point.lat() < -90.0) {
|
||||||
throw new IllegalArgumentException("illegal latitude value [" + point.lat() + "] for " + name());
|
throw new IllegalArgumentException("illegal latitude value [" + point.lat() + "] for " + name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (validateLon) {
|
if (fieldType().validateLon()) {
|
||||||
if (point.lon() > 180.0 || point.lon() < -180) {
|
if (point.lon() > 180.0 || point.lon() < -180) {
|
||||||
throw new IllegalArgumentException("illegal longitude value [" + point.lon() + "] for " + name());
|
throw new IllegalArgumentException("illegal longitude value [" + point.lon() + "] for " + name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
||||||
Field field = new Field(names.indexName(), Double.toString(point.lat()) + ',' + Double.toString(point.lon()), fieldType);
|
Field field = new Field(fieldType.names().indexName(), Double.toString(point.lat()) + ',' + Double.toString(point.lon()), fieldType);
|
||||||
context.doc().add(field);
|
context.doc().add(field);
|
||||||
}
|
}
|
||||||
if (enableGeoHash) {
|
if (fieldType().isGeohashEnabled()) {
|
||||||
if (geohash == null) {
|
if (geohash == null) {
|
||||||
geohash = GeoHashUtils.encode(point.lat(), point.lon());
|
geohash = GeoHashUtils.encode(point.lat(), point.lon());
|
||||||
}
|
}
|
||||||
parseGeohashField(context, geohash);
|
addGeohashField(context, geohash);
|
||||||
}
|
}
|
||||||
if (enableLatLon) {
|
if (fieldType().isLatLonEnabled()) {
|
||||||
latMapper.parse(context.createExternalValueContext(point.lat()));
|
latMapper.parse(context.createExternalValueContext(point.lat()));
|
||||||
lonMapper.parse(context.createExternalValueContext(point.lon()));
|
lonMapper.parse(context.createExternalValueContext(point.lon()));
|
||||||
}
|
}
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
CustomGeoPointDocValuesField field = (CustomGeoPointDocValuesField) context.doc().getByKey(names().indexName());
|
CustomGeoPointDocValuesField field = (CustomGeoPointDocValuesField) context.doc().getByKey(fieldType().names().indexName());
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
field = new CustomGeoPointDocValuesField(names().indexName(), point.lat(), point.lon());
|
field = new CustomGeoPointDocValuesField(fieldType().names().indexName(), point.lat(), point.lon());
|
||||||
context.doc().addWithKey(names().indexName(), field);
|
context.doc().addWithKey(fieldType().names().indexName(), field);
|
||||||
} else {
|
} else {
|
||||||
field.add(point.lat(), point.lon());
|
field.add(point.lat(), point.lon());
|
||||||
}
|
}
|
||||||
|
@ -647,42 +707,43 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
}
|
}
|
||||||
GeoPointFieldMapper fieldMergeWith = (GeoPointFieldMapper) mergeWith;
|
GeoPointFieldMapper fieldMergeWith = (GeoPointFieldMapper) mergeWith;
|
||||||
|
|
||||||
if (this.enableLatLon != fieldMergeWith.enableLatLon) {
|
if (this.fieldType().isLatLonEnabled() != fieldMergeWith.fieldType().isLatLonEnabled()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different lat_lon");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different lat_lon");
|
||||||
}
|
}
|
||||||
if (this.enableGeoHash != fieldMergeWith.enableGeoHash) {
|
if (this.fieldType().isGeohashEnabled() != fieldMergeWith.fieldType().isGeohashEnabled()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different geohash");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different geohash");
|
||||||
}
|
}
|
||||||
if (this.geoHashPrecision != fieldMergeWith.geoHashPrecision) {
|
if (this.fieldType().geohashPrecision() != fieldMergeWith.fieldType().geohashPrecision()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different geohash_precision");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different geohash_precision");
|
||||||
}
|
}
|
||||||
if (this.enableGeohashPrefix != fieldMergeWith.enableGeohashPrefix) {
|
if (this.fieldType().isGeohashPrefixEnabled() != fieldMergeWith.fieldType().isGeohashPrefixEnabled()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different geohash_prefix");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different geohash_prefix");
|
||||||
}
|
}
|
||||||
if (this.normalizeLat != fieldMergeWith.normalizeLat) {
|
if (this.fieldType().normalizeLat() != fieldMergeWith.fieldType().normalizeLat()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different normalize_lat");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different normalize_lat");
|
||||||
}
|
}
|
||||||
if (this.normalizeLon != fieldMergeWith.normalizeLon) {
|
if (this.fieldType().normalizeLon() != fieldMergeWith.fieldType().normalizeLon()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different normalize_lon");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different normalize_lon");
|
||||||
}
|
}
|
||||||
if (!Objects.equal(this.precisionStep, fieldMergeWith.precisionStep)) {
|
if (fieldType().isLatLonEnabled() &&
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different precision_step");
|
this.fieldType().latFieldType().numericPrecisionStep() != fieldMergeWith.fieldType().latFieldType().numericPrecisionStep()) {
|
||||||
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different precision_step");
|
||||||
}
|
}
|
||||||
if (this.validateLat != fieldMergeWith.validateLat) {
|
if (this.fieldType().validateLat() != fieldMergeWith.fieldType().validateLat()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different validate_lat");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different validate_lat");
|
||||||
}
|
}
|
||||||
if (this.validateLon != fieldMergeWith.validateLon) {
|
if (this.fieldType().validateLon() != fieldMergeWith.fieldType().validateLon()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different validate_lon");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different validate_lon");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Mapper> iterator() {
|
public Iterator<Mapper> iterator() {
|
||||||
List<Mapper> extras = new ArrayList<>();
|
List<Mapper> extras = new ArrayList<>();
|
||||||
if (enableGeoHash) {
|
if (fieldType().isGeohashEnabled()) {
|
||||||
extras.add(geohashMapper);
|
extras.add(geohashMapper);
|
||||||
}
|
}
|
||||||
if (enableLatLon) {
|
if (fieldType().isLatLonEnabled()) {
|
||||||
extras.add(latMapper);
|
extras.add(latMapper);
|
||||||
extras.add(lonMapper);
|
extras.add(lonMapper);
|
||||||
}
|
}
|
||||||
|
@ -695,46 +756,46 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
if (includeDefaults || pathType != Defaults.PATH_TYPE) {
|
if (includeDefaults || pathType != Defaults.PATH_TYPE) {
|
||||||
builder.field("path", pathType.name().toLowerCase(Locale.ROOT));
|
builder.field("path", pathType.name().toLowerCase(Locale.ROOT));
|
||||||
}
|
}
|
||||||
if (includeDefaults || enableLatLon != Defaults.ENABLE_LATLON) {
|
if (includeDefaults || fieldType().isLatLonEnabled() != Defaults.ENABLE_LATLON) {
|
||||||
builder.field("lat_lon", enableLatLon);
|
builder.field("lat_lon", fieldType().isLatLonEnabled());
|
||||||
}
|
}
|
||||||
if (includeDefaults || enableGeoHash != Defaults.ENABLE_GEOHASH) {
|
if (includeDefaults || fieldType().isGeohashEnabled() != Defaults.ENABLE_GEOHASH) {
|
||||||
builder.field("geohash", enableGeoHash);
|
builder.field("geohash", fieldType().isGeohashEnabled());
|
||||||
}
|
}
|
||||||
if (includeDefaults || enableGeohashPrefix != Defaults.ENABLE_GEOHASH_PREFIX) {
|
if (includeDefaults || fieldType().isGeohashPrefixEnabled() != Defaults.ENABLE_GEOHASH_PREFIX) {
|
||||||
builder.field("geohash_prefix", enableGeohashPrefix);
|
builder.field("geohash_prefix", fieldType().isGeohashPrefixEnabled());
|
||||||
}
|
}
|
||||||
if (includeDefaults || geoHashPrecision != Defaults.GEO_HASH_PRECISION) {
|
if (fieldType().isGeohashEnabled() && (includeDefaults || fieldType().geohashPrecision() != Defaults.GEO_HASH_PRECISION)) {
|
||||||
builder.field("geohash_precision", geoHashPrecision);
|
builder.field("geohash_precision", fieldType().geohashPrecision());
|
||||||
}
|
}
|
||||||
if (includeDefaults || precisionStep != null) {
|
if (fieldType().isLatLonEnabled() && (includeDefaults || fieldType().latFieldType().numericPrecisionStep() != NumericUtils.PRECISION_STEP_DEFAULT)) {
|
||||||
builder.field("precision_step", precisionStep);
|
builder.field("precision_step", fieldType().latFieldType().numericPrecisionStep());
|
||||||
}
|
}
|
||||||
if (includeDefaults || validateLat != Defaults.VALIDATE_LAT || validateLon != Defaults.VALIDATE_LON) {
|
if (includeDefaults || fieldType().validateLat() != Defaults.VALIDATE_LAT || fieldType().validateLon() != Defaults.VALIDATE_LON) {
|
||||||
if (validateLat && validateLon) {
|
if (fieldType().validateLat() && fieldType().validateLon()) {
|
||||||
builder.field("validate", true);
|
builder.field("validate", true);
|
||||||
} else if (!validateLat && !validateLon) {
|
} else if (!fieldType().validateLat() && !fieldType().validateLon()) {
|
||||||
builder.field("validate", false);
|
builder.field("validate", false);
|
||||||
} else {
|
} else {
|
||||||
if (includeDefaults || validateLat != Defaults.VALIDATE_LAT) {
|
if (includeDefaults || fieldType().validateLat() != Defaults.VALIDATE_LAT) {
|
||||||
builder.field("validate_lat", validateLat);
|
builder.field("validate_lat", fieldType().validateLat());
|
||||||
}
|
}
|
||||||
if (includeDefaults || validateLon != Defaults.VALIDATE_LON) {
|
if (includeDefaults || fieldType().validateLon() != Defaults.VALIDATE_LON) {
|
||||||
builder.field("validate_lon", validateLon);
|
builder.field("validate_lon", fieldType().validateLon());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (includeDefaults || normalizeLat != Defaults.NORMALIZE_LAT || normalizeLon != Defaults.NORMALIZE_LON) {
|
if (includeDefaults || fieldType().normalizeLat() != Defaults.NORMALIZE_LAT || fieldType().normalizeLon() != Defaults.NORMALIZE_LON) {
|
||||||
if (normalizeLat && normalizeLon) {
|
if (fieldType().normalizeLat() && fieldType().normalizeLon()) {
|
||||||
builder.field("normalize", true);
|
builder.field("normalize", true);
|
||||||
} else if (!normalizeLat && !normalizeLon) {
|
} else if (!fieldType().normalizeLat() && !fieldType().normalizeLon()) {
|
||||||
builder.field("normalize", false);
|
builder.field("normalize", false);
|
||||||
} else {
|
} else {
|
||||||
if (includeDefaults || normalizeLat != Defaults.NORMALIZE_LAT) {
|
if (includeDefaults || fieldType().normalizeLat() != Defaults.NORMALIZE_LAT) {
|
||||||
builder.field("normalize_lat", normalizeLat);
|
builder.field("normalize_lat", fieldType().normalizeLat());
|
||||||
}
|
}
|
||||||
if (includeDefaults || normalizeLon != Defaults.NORMALIZE_LON) {
|
if (includeDefaults || fieldType().normalizeLon() != Defaults.NORMALIZE_LON) {
|
||||||
builder.field("normalize_lon", normalizeLat);
|
builder.field("normalize_lon", fieldType().normalizeLon());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -742,15 +803,9 @@ public class GeoPointFieldMapper extends AbstractFieldMapper implements ArrayVal
|
||||||
|
|
||||||
public static class CustomGeoPointDocValuesField extends CustomNumericDocValuesField {
|
public static class CustomGeoPointDocValuesField extends CustomNumericDocValuesField {
|
||||||
|
|
||||||
public static final FieldType TYPE = new FieldType();
|
|
||||||
static {
|
|
||||||
TYPE.setDocValuesType(DocValuesType.BINARY);
|
|
||||||
TYPE.freeze();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ObjectHashSet<GeoPoint> points;
|
private final ObjectHashSet<GeoPoint> points;
|
||||||
|
|
||||||
public CustomGeoPointDocValuesField(String name, double lat, double lon) {
|
public CustomGeoPointDocValuesField(String name, double lat, double lon) {
|
||||||
super(name);
|
super(name);
|
||||||
points = new ObjectHashSet<>(2);
|
points = new ObjectHashSet<>(2);
|
||||||
points.add(new GeoPoint(lat, lon));
|
points.add(new GeoPoint(lat, lon));
|
||||||
|
|
|
@ -20,7 +20,6 @@ package org.elasticsearch.index.mapper.geo;
|
||||||
|
|
||||||
import com.spatial4j.core.shape.Shape;
|
import com.spatial4j.core.shape.Shape;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.spatial.prefix.PrefixTreeStrategy;
|
import org.apache.lucene.spatial.prefix.PrefixTreeStrategy;
|
||||||
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
|
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
|
||||||
|
@ -40,10 +39,11 @@ import org.elasticsearch.common.unit.DistanceUnit;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeResult;
|
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ public class GeoShapeFieldMapper extends AbstractFieldMapper {
|
||||||
public static final double DISTANCE_ERROR_PCT = 0.025d;
|
public static final double DISTANCE_ERROR_PCT = 0.025d;
|
||||||
public static final Orientation ORIENTATION = Orientation.RIGHT;
|
public static final Orientation ORIENTATION = Orientation.RIGHT;
|
||||||
|
|
||||||
public static final FieldType FIELD_TYPE = new FieldType();
|
public static final MappedFieldType FIELD_TYPE = new GeoShapeFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
||||||
|
@ -119,7 +119,7 @@ public class GeoShapeFieldMapper extends AbstractFieldMapper {
|
||||||
private SpatialPrefixTree prefixTree;
|
private SpatialPrefixTree prefixTree;
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE));
|
super(name, Defaults.FIELD_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder tree(String tree) {
|
public Builder tree(String tree) {
|
||||||
|
@ -155,7 +155,6 @@ public class GeoShapeFieldMapper extends AbstractFieldMapper {
|
||||||
@Override
|
@Override
|
||||||
public GeoShapeFieldMapper build(BuilderContext context) {
|
public GeoShapeFieldMapper build(BuilderContext context) {
|
||||||
|
|
||||||
final FieldMapper.Names names = buildNames(context);
|
|
||||||
if (Names.TREE_GEOHASH.equals(tree)) {
|
if (Names.TREE_GEOHASH.equals(tree)) {
|
||||||
prefixTree = new GeohashPrefixTree(ShapeBuilder.SPATIAL_CONTEXT, getLevels(treeLevels, precisionInMeters, Defaults.GEOHASH_LEVELS, true));
|
prefixTree = new GeohashPrefixTree(ShapeBuilder.SPATIAL_CONTEXT, getLevels(treeLevels, precisionInMeters, Defaults.GEOHASH_LEVELS, true));
|
||||||
} else if (Names.TREE_QUADTREE.equals(tree)) {
|
} else if (Names.TREE_QUADTREE.equals(tree)) {
|
||||||
|
@ -169,9 +168,19 @@ public class GeoShapeFieldMapper extends AbstractFieldMapper {
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unknown prefix tree type [" + tree + "]");
|
throw new IllegalArgumentException("Unknown prefix tree type [" + tree + "]");
|
||||||
}
|
}
|
||||||
|
setupFieldType(context);
|
||||||
|
|
||||||
return new GeoShapeFieldMapper(names, prefixTree, strategyName, distanceErrorPct, orientation, fieldType,
|
RecursivePrefixTreeStrategy recursiveStrategy = new RecursivePrefixTreeStrategy(prefixTree, fieldType.names().indexName());
|
||||||
context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
recursiveStrategy.setDistErrPct(distanceErrorPct);
|
||||||
|
recursiveStrategy.setPruneLeafyBranches(false);
|
||||||
|
TermQueryPrefixTreeStrategy termStrategy = new TermQueryPrefixTreeStrategy(prefixTree, fieldType.names().indexName());
|
||||||
|
termStrategy.setDistErrPct(distanceErrorPct);
|
||||||
|
|
||||||
|
GeoShapeFieldType geoShapeFieldType = (GeoShapeFieldType)fieldType;
|
||||||
|
geoShapeFieldType.setStrategies(strategyName, recursiveStrategy, termStrategy);
|
||||||
|
geoShapeFieldType.setOrientation(orientation);
|
||||||
|
|
||||||
|
return new GeoShapeFieldMapper(fieldType, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final int getLevels(int treeLevels, double precisionInMeters, int defaultLevels, boolean geoHash) {
|
private final int getLevels(int treeLevels, double precisionInMeters, int defaultLevels, boolean geoHash) {
|
||||||
|
@ -223,25 +232,83 @@ public class GeoShapeFieldMapper extends AbstractFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final PrefixTreeStrategy defaultStrategy;
|
public static class GeoShapeFieldType extends MappedFieldType {
|
||||||
private final RecursivePrefixTreeStrategy recursiveStrategy;
|
|
||||||
private final TermQueryPrefixTreeStrategy termStrategy;
|
|
||||||
private Orientation shapeOrientation;
|
|
||||||
|
|
||||||
public GeoShapeFieldMapper(FieldMapper.Names names, SpatialPrefixTree tree, String defaultStrategyName, double distanceErrorPct,
|
private PrefixTreeStrategy defaultStrategy;
|
||||||
Orientation shapeOrientation, FieldType fieldType, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
private RecursivePrefixTreeStrategy recursiveStrategy;
|
||||||
super(names, 1, fieldType, false, null, null, null, null, null, indexSettings, multiFields, copyTo);
|
private TermQueryPrefixTreeStrategy termStrategy;
|
||||||
this.recursiveStrategy = new RecursivePrefixTreeStrategy(tree, names.indexName());
|
private Orientation orientation;
|
||||||
this.recursiveStrategy.setDistErrPct(distanceErrorPct);
|
|
||||||
this.recursiveStrategy.setPruneLeafyBranches(false);
|
public GeoShapeFieldType() {
|
||||||
this.termStrategy = new TermQueryPrefixTreeStrategy(tree, names.indexName());
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
this.termStrategy.setDistErrPct(distanceErrorPct);
|
}
|
||||||
this.defaultStrategy = resolveStrategy(defaultStrategyName);
|
|
||||||
this.shapeOrientation = shapeOrientation;
|
protected GeoShapeFieldType(GeoShapeFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
// TODO: this shallow copy is probably not good...need to extract the parameters and recreate the tree and strategies?
|
||||||
|
this.defaultStrategy = ref.defaultStrategy;
|
||||||
|
this.recursiveStrategy = ref.recursiveStrategy;
|
||||||
|
this.termStrategy = ref.termStrategy;
|
||||||
|
this.orientation = ref.orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new GeoShapeFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrefixTreeStrategy defaultStrategy() {
|
||||||
|
return this.defaultStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrefixTreeStrategy resolveStrategy(String strategyName) {
|
||||||
|
if (SpatialStrategy.RECURSIVE.getStrategyName().equals(strategyName)) {
|
||||||
|
return recursiveStrategy;
|
||||||
|
}
|
||||||
|
if (SpatialStrategy.TERM.getStrategyName().equals(strategyName)) {
|
||||||
|
return termStrategy;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unknown prefix tree strategy [" + strategyName + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStrategies(String defaultStrategy, RecursivePrefixTreeStrategy recursiveStrategy, TermQueryPrefixTreeStrategy termStrategy) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.recursiveStrategy = recursiveStrategy;
|
||||||
|
this.termStrategy = termStrategy;
|
||||||
|
this.defaultStrategy = resolveStrategy(defaultStrategy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDistErrPct(double distErrPct) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.recursiveStrategy.setDistErrPct(distErrPct);
|
||||||
|
this.termStrategy.setDistErrPct(distErrPct);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Orientation orientation() { return this.orientation; }
|
||||||
|
|
||||||
|
public void setOrientation(Orientation orientation) {
|
||||||
|
checkIfFrozen();
|
||||||
|
this.orientation = orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String value(Object value) {
|
||||||
|
throw new UnsupportedOperationException("GeoShape fields cannot be converted to String values");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public GeoShapeFieldMapper(MappedFieldType fieldType, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||||
|
super(fieldType, false, null, indexSettings, multiFields, copyTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public GeoShapeFieldType fieldType() {
|
||||||
|
return (GeoShapeFieldType)fieldType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,18 +328,18 @@ public class GeoShapeFieldMapper extends AbstractFieldMapper {
|
||||||
}
|
}
|
||||||
shape = shapeBuilder.build();
|
shape = shapeBuilder.build();
|
||||||
}
|
}
|
||||||
Field[] fields = defaultStrategy.createIndexableFields(shape);
|
Field[] fields = fieldType().defaultStrategy().createIndexableFields(shape);
|
||||||
if (fields == null || fields.length == 0) {
|
if (fields == null || fields.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
for (Field field : fields) {
|
for (Field field : fields) {
|
||||||
if (!customBoost()) {
|
if (!customBoost()) {
|
||||||
field.setBoost(boost);
|
field.setBoost(fieldType.boost());
|
||||||
}
|
}
|
||||||
context.doc().add(field);
|
context.doc().add(field);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new MapperParsingException("failed to parse [" + names.fullName() + "]", e);
|
throw new MapperParsingException("failed to parse [" + fieldType.names().fullName() + "]", e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -281,29 +348,29 @@ public class GeoShapeFieldMapper extends AbstractFieldMapper {
|
||||||
public void merge(Mapper mergeWith, MergeResult mergeResult) throws MergeMappingException {
|
public void merge(Mapper mergeWith, MergeResult mergeResult) throws MergeMappingException {
|
||||||
super.merge(mergeWith, mergeResult);
|
super.merge(mergeWith, mergeResult);
|
||||||
if (!this.getClass().equals(mergeWith.getClass())) {
|
if (!this.getClass().equals(mergeWith.getClass())) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different field type");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different field type");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final GeoShapeFieldMapper fieldMergeWith = (GeoShapeFieldMapper) mergeWith;
|
final GeoShapeFieldMapper fieldMergeWith = (GeoShapeFieldMapper) mergeWith;
|
||||||
final PrefixTreeStrategy mergeWithStrategy = fieldMergeWith.defaultStrategy;
|
final PrefixTreeStrategy mergeWithStrategy = fieldMergeWith.fieldType().defaultStrategy();
|
||||||
|
|
||||||
// prevent user from changing strategies
|
// prevent user from changing strategies
|
||||||
if (!(this.defaultStrategy.getClass().equals(mergeWithStrategy.getClass()))) {
|
if (!(this.fieldType().defaultStrategy().getClass().equals(mergeWithStrategy.getClass()))) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different strategy");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different strategy");
|
||||||
}
|
}
|
||||||
|
|
||||||
final SpatialPrefixTree grid = this.defaultStrategy.getGrid();
|
final SpatialPrefixTree grid = this.fieldType().defaultStrategy().getGrid();
|
||||||
final SpatialPrefixTree mergeGrid = mergeWithStrategy.getGrid();
|
final SpatialPrefixTree mergeGrid = mergeWithStrategy.getGrid();
|
||||||
|
|
||||||
// prevent user from changing trees (changes encoding)
|
// prevent user from changing trees (changes encoding)
|
||||||
if (!grid.getClass().equals(mergeGrid.getClass())) {
|
if (!grid.getClass().equals(mergeGrid.getClass())) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different tree");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different tree");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO we should allow this, but at the moment levels is used to build bookkeeping variables
|
// TODO we should allow this, but at the moment levels is used to build bookkeeping variables
|
||||||
// in lucene's SpatialPrefixTree implementations, need a patch to correct that first
|
// in lucene's SpatialPrefixTree implementations, need a patch to correct that first
|
||||||
if (grid.getMaxLevels() != mergeGrid.getMaxLevels()) {
|
if (grid.getMaxLevels() != mergeGrid.getMaxLevels()) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] has different tree_levels or precision");
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] has different tree_levels or precision");
|
||||||
}
|
}
|
||||||
|
|
||||||
// bail if there were merge conflicts
|
// bail if there were merge conflicts
|
||||||
|
@ -312,11 +379,12 @@ public class GeoShapeFieldMapper extends AbstractFieldMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
// change distance error percent
|
// change distance error percent
|
||||||
this.defaultStrategy.setDistErrPct(mergeWithStrategy.getDistErrPct());
|
this.fieldType = this.fieldType.clone();
|
||||||
|
this.fieldType().setDistErrPct(mergeWithStrategy.getDistErrPct());
|
||||||
// change orientation - this is allowed because existing dateline spanning shapes
|
// change orientation - this is allowed because existing dateline spanning shapes
|
||||||
// have already been unwound and segmented
|
// have already been unwound and segmented
|
||||||
this.shapeOrientation = fieldMergeWith.shapeOrientation;
|
this.fieldType().setOrientation(fieldMergeWith.fieldType().orientation());
|
||||||
|
this.fieldType.freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -328,25 +396,25 @@ public class GeoShapeFieldMapper extends AbstractFieldMapper {
|
||||||
builder.field("type", contentType());
|
builder.field("type", contentType());
|
||||||
|
|
||||||
// TODO: Come up with a better way to get the name, maybe pass it from builder
|
// TODO: Come up with a better way to get the name, maybe pass it from builder
|
||||||
if (defaultStrategy.getGrid() instanceof GeohashPrefixTree) {
|
if (fieldType().defaultStrategy().getGrid() instanceof GeohashPrefixTree) {
|
||||||
// Don't emit the tree name since GeohashPrefixTree is the default
|
// Don't emit the tree name since GeohashPrefixTree is the default
|
||||||
// Only emit the tree levels if it isn't the default value
|
// Only emit the tree levels if it isn't the default value
|
||||||
if (includeDefaults || defaultStrategy.getGrid().getMaxLevels() != Defaults.GEOHASH_LEVELS) {
|
if (includeDefaults || fieldType().defaultStrategy().getGrid().getMaxLevels() != Defaults.GEOHASH_LEVELS) {
|
||||||
builder.field(Names.TREE_LEVELS, defaultStrategy.getGrid().getMaxLevels());
|
builder.field(Names.TREE_LEVELS, fieldType().defaultStrategy().getGrid().getMaxLevels());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
builder.field(Names.TREE, Names.TREE_QUADTREE);
|
builder.field(Names.TREE, Names.TREE_QUADTREE);
|
||||||
if (includeDefaults || defaultStrategy.getGrid().getMaxLevels() != Defaults.QUADTREE_LEVELS) {
|
if (includeDefaults || fieldType().defaultStrategy().getGrid().getMaxLevels() != Defaults.QUADTREE_LEVELS) {
|
||||||
builder.field(Names.TREE_LEVELS, defaultStrategy.getGrid().getMaxLevels());
|
builder.field(Names.TREE_LEVELS, fieldType().defaultStrategy().getGrid().getMaxLevels());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (includeDefaults || defaultStrategy.getDistErrPct() != Defaults.DISTANCE_ERROR_PCT) {
|
if (includeDefaults || fieldType().defaultStrategy().getDistErrPct() != Defaults.DISTANCE_ERROR_PCT) {
|
||||||
builder.field(Names.DISTANCE_ERROR_PCT, defaultStrategy.getDistErrPct());
|
builder.field(Names.DISTANCE_ERROR_PCT, fieldType().defaultStrategy().getDistErrPct());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (includeDefaults || orientation() != Defaults.ORIENTATION) {
|
if (includeDefaults || fieldType().orientation() != Defaults.ORIENTATION) {
|
||||||
builder.field(Names.ORIENTATION, orientation());
|
builder.field(Names.ORIENTATION, fieldType().orientation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,34 +422,4 @@ public class GeoShapeFieldMapper extends AbstractFieldMapper {
|
||||||
protected String contentType() {
|
protected String contentType() {
|
||||||
return CONTENT_TYPE;
|
return CONTENT_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String value(Object value) {
|
|
||||||
throw new UnsupportedOperationException("GeoShape fields cannot be converted to String values");
|
|
||||||
}
|
|
||||||
|
|
||||||
public PrefixTreeStrategy defaultStrategy() {
|
|
||||||
return this.defaultStrategy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PrefixTreeStrategy recursiveStrategy() {
|
|
||||||
return this.recursiveStrategy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PrefixTreeStrategy termStrategy() {
|
|
||||||
return this.termStrategy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Orientation orientation() { return this.shapeOrientation; }
|
|
||||||
|
|
||||||
public PrefixTreeStrategy resolveStrategy(String strategyName) {
|
|
||||||
if (SpatialStrategy.RECURSIVE.getStrategyName().equals(strategyName)) {
|
|
||||||
return recursiveStrategy;
|
|
||||||
}
|
|
||||||
if (SpatialStrategy.TERM.getStrategyName().equals(strategyName)) {
|
|
||||||
return termStrategy;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Unknown prefix tree strategy [" + strategyName + "]");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ package org.elasticsearch.index.mapper.internal;
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
|
@ -34,8 +33,8 @@ import org.elasticsearch.common.lucene.all.AllField;
|
||||||
import org.elasticsearch.common.lucene.all.AllTermQuery;
|
import org.elasticsearch.common.lucene.all.AllTermQuery;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -45,7 +44,6 @@ import org.elasticsearch.index.mapper.RootMapper;
|
||||||
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.index.similarity.SimilarityLookupService;
|
import org.elasticsearch.index.similarity.SimilarityLookupService;
|
||||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -80,11 +78,12 @@ public class AllFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
public static final String INDEX_NAME = AllFieldMapper.NAME;
|
public static final String INDEX_NAME = AllFieldMapper.NAME;
|
||||||
public static final EnabledAttributeMapper ENABLED = EnabledAttributeMapper.UNSET_ENABLED;
|
public static final EnabledAttributeMapper ENABLED = EnabledAttributeMapper.UNSET_ENABLED;
|
||||||
|
|
||||||
public static final FieldType FIELD_TYPE = new FieldType();
|
public static final MappedFieldType FIELD_TYPE = new AllFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS);
|
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS);
|
||||||
FIELD_TYPE.setTokenized(true);
|
FIELD_TYPE.setTokenized(true);
|
||||||
|
FIELD_TYPE.setNames(new MappedFieldType.Names(NAME));
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +93,7 @@ public class AllFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
private EnabledAttributeMapper enabled = Defaults.ENABLED;
|
private EnabledAttributeMapper enabled = Defaults.ENABLED;
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
super(Defaults.NAME, new FieldType(Defaults.FIELD_TYPE));
|
super(Defaults.NAME, Defaults.FIELD_TYPE);
|
||||||
builder = this;
|
builder = this;
|
||||||
indexName = Defaults.INDEX_NAME;
|
indexName = Defaults.INDEX_NAME;
|
||||||
}
|
}
|
||||||
|
@ -113,7 +112,7 @@ public class AllFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
}
|
}
|
||||||
fieldType.setTokenized(true);
|
fieldType.setTokenized(true);
|
||||||
|
|
||||||
return new AllFieldMapper(name, fieldType, indexAnalyzer, searchAnalyzer, enabled, similarity, normsLoading, fieldDataSettings, context.indexSettings());
|
return new AllFieldMapper(fieldType, enabled, fieldDataSettings, context.indexSettings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,18 +155,49 @@ public class AllFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class AllFieldType extends MappedFieldType {
|
||||||
|
|
||||||
|
public AllFieldType() {
|
||||||
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AllFieldType(AllFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new AllFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query queryStringTermQuery(Term term) {
|
||||||
|
return new AllTermQuery(term);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query termQuery(Object value, QueryParseContext context) {
|
||||||
|
return queryStringTermQuery(createTerm(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private EnabledAttributeMapper enabledState;
|
private EnabledAttributeMapper enabledState;
|
||||||
|
|
||||||
public AllFieldMapper(Settings indexSettings) {
|
public AllFieldMapper(Settings indexSettings) {
|
||||||
this(Defaults.NAME, new FieldType(Defaults.FIELD_TYPE), null, null, Defaults.ENABLED, null, null, null, indexSettings);
|
this(Defaults.FIELD_TYPE.clone(), Defaults.ENABLED, null, indexSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AllFieldMapper(String name, FieldType fieldType, NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer,
|
protected AllFieldMapper(MappedFieldType fieldType, EnabledAttributeMapper enabled,
|
||||||
EnabledAttributeMapper enabled, SimilarityProvider similarity, Loading normsLoading,
|
|
||||||
@Nullable Settings fieldDataSettings, Settings indexSettings) {
|
@Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||||
super(new Names(name, name, name, name), 1.0f, fieldType, false, indexAnalyzer, searchAnalyzer,
|
super(fieldType, false, fieldDataSettings, indexSettings);
|
||||||
similarity, normsLoading, fieldDataSettings, indexSettings);
|
|
||||||
this.enabledState = enabled;
|
this.enabledState = enabled;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -177,7 +207,7 @@ public class AllFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,16 +216,6 @@ public class AllFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
return new FieldDataType("string");
|
return new FieldDataType("string");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query queryStringTermQuery(Term term) {
|
|
||||||
return new AllTermQuery(term);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query termQuery(Object value, QueryParseContext context) {
|
|
||||||
return queryStringTermQuery(createTerm(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preParse(ParseContext context) throws IOException {
|
public void preParse(ParseContext context) throws IOException {
|
||||||
}
|
}
|
||||||
|
@ -219,11 +239,11 @@ public class AllFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
// reset the entries
|
// reset the entries
|
||||||
context.allEntries().reset();
|
context.allEntries().reset();
|
||||||
Analyzer analyzer = findAnalyzer(context);
|
Analyzer analyzer = findAnalyzer(context);
|
||||||
fields.add(new AllField(names.indexName(), context.allEntries(), analyzer, fieldType));
|
fields.add(new AllField(fieldType.names().indexName(), context.allEntries(), analyzer, fieldType));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Analyzer findAnalyzer(ParseContext context) {
|
private Analyzer findAnalyzer(ParseContext context) {
|
||||||
Analyzer analyzer = indexAnalyzer;
|
Analyzer analyzer = fieldType.indexAnalyzer();
|
||||||
if (analyzer == null) {
|
if (analyzer == null) {
|
||||||
analyzer = context.docMapper().mappers().indexAnalyzer();
|
analyzer = context.docMapper().mappers().indexAnalyzer();
|
||||||
if (analyzer == null) {
|
if (analyzer == null) {
|
||||||
|
@ -233,14 +253,6 @@ public class AllFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
}
|
}
|
||||||
return analyzer;
|
return analyzer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String contentType() {
|
protected String contentType() {
|
||||||
|
@ -294,8 +306,8 @@ public class AllFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
|
|
||||||
doXContentAnalyzers(builder, includeDefaults);
|
doXContentAnalyzers(builder, includeDefaults);
|
||||||
|
|
||||||
if (similarity() != null) {
|
if (fieldType().similarity() != null) {
|
||||||
builder.field("similarity", similarity().name());
|
builder.field("similarity", fieldType().similarity().name());
|
||||||
} else if (includeDefaults) {
|
} else if (includeDefaults) {
|
||||||
builder.field("similarity", SimilarityLookupService.DEFAULT_SIMILARITY);
|
builder.field("similarity", SimilarityLookupService.DEFAULT_SIMILARITY);
|
||||||
}
|
}
|
||||||
|
@ -303,14 +315,14 @@ public class AllFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
if (customFieldDataSettings != null) {
|
if (customFieldDataSettings != null) {
|
||||||
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
||||||
} else if (includeDefaults) {
|
} else if (includeDefaults) {
|
||||||
builder.field("fielddata", (Map) fieldDataType.getSettings().getAsMap());
|
builder.field("fielddata", (Map) fieldType.fieldDataType().getSettings().getAsMap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void merge(Mapper mergeWith, MergeResult mergeResult) throws MergeMappingException {
|
public void merge(Mapper mergeWith, MergeResult mergeResult) throws MergeMappingException {
|
||||||
if (((AllFieldMapper)mergeWith).enabled() != this.enabled() && ((AllFieldMapper)mergeWith).enabledState != Defaults.ENABLED) {
|
if (((AllFieldMapper)mergeWith).enabled() != this.enabled() && ((AllFieldMapper)mergeWith).enabledState != Defaults.ENABLED) {
|
||||||
mergeResult.addConflict("mapper [" + names.fullName() + "] enabled is " + this.enabled() + " now encountering "+ ((AllFieldMapper)mergeWith).enabled());
|
mergeResult.addConflict("mapper [" + fieldType.names().fullName() + "] enabled is " + this.enabled() + " now encountering "+ ((AllFieldMapper)mergeWith).enabled());
|
||||||
}
|
}
|
||||||
super.merge(mergeWith, mergeResult);
|
super.merge(mergeWith, mergeResult);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.elasticsearch.common.lucene.Lucene;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -38,6 +39,7 @@ import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.mapper.RootMapper;
|
import org.elasticsearch.index.mapper.RootMapper;
|
||||||
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
||||||
|
import org.elasticsearch.search.highlight.HighlightBuilder;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -65,13 +67,16 @@ public class FieldNamesFieldMapper extends AbstractFieldMapper implements RootMa
|
||||||
public static final String NAME = FieldNamesFieldMapper.NAME;
|
public static final String NAME = FieldNamesFieldMapper.NAME;
|
||||||
|
|
||||||
public static final EnabledAttributeMapper ENABLED_STATE = EnabledAttributeMapper.UNSET_ENABLED;
|
public static final EnabledAttributeMapper ENABLED_STATE = EnabledAttributeMapper.UNSET_ENABLED;
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new FieldNamesFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
||||||
FIELD_TYPE.setTokenized(false);
|
FIELD_TYPE.setTokenized(false);
|
||||||
FIELD_TYPE.setStored(false);
|
FIELD_TYPE.setStored(false);
|
||||||
FIELD_TYPE.setOmitNorms(true);
|
FIELD_TYPE.setOmitNorms(true);
|
||||||
|
FIELD_TYPE.setIndexAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setNames(new MappedFieldType.Names(NAME));
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +85,7 @@ public class FieldNamesFieldMapper extends AbstractFieldMapper implements RootMa
|
||||||
private EnabledAttributeMapper enabledState = Defaults.ENABLED_STATE;
|
private EnabledAttributeMapper enabledState = Defaults.ENABLED_STATE;
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
super(Defaults.NAME, new FieldType(Defaults.FIELD_TYPE));
|
super(Defaults.NAME, Defaults.FIELD_TYPE);
|
||||||
indexName = Defaults.NAME;
|
indexName = Defaults.NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +103,8 @@ public class FieldNamesFieldMapper extends AbstractFieldMapper implements RootMa
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldNamesFieldMapper build(BuilderContext context) {
|
public FieldNamesFieldMapper build(BuilderContext context) {
|
||||||
return new FieldNamesFieldMapper(name, indexName, boost, fieldType, enabledState, fieldDataSettings, context.indexSettings());
|
fieldType.setNames(new MappedFieldType.Names(name, indexName, indexName, name));
|
||||||
|
return new FieldNamesFieldMapper(fieldType, enabledState, fieldDataSettings, context.indexSettings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,17 +133,45 @@ public class FieldNamesFieldMapper extends AbstractFieldMapper implements RootMa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final FieldType defaultFieldType;
|
public static class FieldNamesFieldType extends MappedFieldType {
|
||||||
|
|
||||||
|
public FieldNamesFieldType() {
|
||||||
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected FieldNamesFieldType(FieldNamesFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new FieldNamesFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useTermQueryWithQueryString() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final MappedFieldType defaultFieldType;
|
||||||
private EnabledAttributeMapper enabledState;
|
private EnabledAttributeMapper enabledState;
|
||||||
private final boolean pre13Index; // if the index was created before 1.3, _field_names is always disabled
|
private final boolean pre13Index; // if the index was created before 1.3, _field_names is always disabled
|
||||||
|
|
||||||
public FieldNamesFieldMapper(Settings indexSettings) {
|
public FieldNamesFieldMapper(Settings indexSettings) {
|
||||||
this(Defaults.NAME, Defaults.NAME, Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), Defaults.ENABLED_STATE, null, indexSettings);
|
this(Defaults.FIELD_TYPE.clone(), Defaults.ENABLED_STATE, null, indexSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldNamesFieldMapper(String name, String indexName, float boost, FieldType fieldType, EnabledAttributeMapper enabledState, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
public FieldNamesFieldMapper(MappedFieldType fieldType, EnabledAttributeMapper enabledState, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||||
super(new Names(name, indexName, indexName, name), boost, fieldType, false, Lucene.KEYWORD_ANALYZER,
|
super(fieldType, false, fieldDataSettings, indexSettings);
|
||||||
Lucene.KEYWORD_ANALYZER, null, null, fieldDataSettings, indexSettings);
|
|
||||||
this.defaultFieldType = Defaults.FIELD_TYPE;
|
this.defaultFieldType = Defaults.FIELD_TYPE;
|
||||||
this.pre13Index = Version.indexCreated(indexSettings).before(Version.V_1_3_0);
|
this.pre13Index = Version.indexCreated(indexSettings).before(Version.V_1_3_0);
|
||||||
this.enabledState = enabledState;
|
this.enabledState = enabledState;
|
||||||
|
@ -148,7 +182,7 @@ public class FieldNamesFieldMapper extends AbstractFieldMapper implements RootMa
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return defaultFieldType;
|
return defaultFieldType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,19 +191,6 @@ public class FieldNamesFieldMapper extends AbstractFieldMapper implements RootMa
|
||||||
return new FieldDataType("string");
|
return new FieldDataType("string");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean useTermQueryWithQueryString() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preParse(ParseContext context) throws IOException {
|
public void preParse(ParseContext context) throws IOException {
|
||||||
}
|
}
|
||||||
|
@ -230,7 +251,7 @@ public class FieldNamesFieldMapper extends AbstractFieldMapper implements RootMa
|
||||||
for (String path : paths) {
|
for (String path : paths) {
|
||||||
for (String fieldName : extractFieldNames(path)) {
|
for (String fieldName : extractFieldNames(path)) {
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
||||||
document.add(new Field(names().indexName(), fieldName, fieldType));
|
document.add(new Field(fieldType().names().indexName(), fieldName, fieldType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ package org.elasticsearch.index.mapper.internal;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import org.apache.lucene.document.BinaryDocValuesField;
|
import org.apache.lucene.document.BinaryDocValuesField;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
import org.apache.lucene.queries.TermsQuery;
|
import org.apache.lucene.queries.TermsQuery;
|
||||||
|
@ -43,6 +42,7 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -73,14 +73,16 @@ public class IdFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
|
|
||||||
public static class Defaults extends AbstractFieldMapper.Defaults {
|
public static class Defaults extends AbstractFieldMapper.Defaults {
|
||||||
public static final String NAME = IdFieldMapper.NAME;
|
public static final String NAME = IdFieldMapper.NAME;
|
||||||
public static final String INDEX_NAME = IdFieldMapper.NAME;
|
|
||||||
|
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new IdFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setIndexOptions(IndexOptions.NONE);
|
FIELD_TYPE.setIndexOptions(IndexOptions.NONE);
|
||||||
FIELD_TYPE.setStored(false);
|
FIELD_TYPE.setStored(false);
|
||||||
FIELD_TYPE.setOmitNorms(true);
|
FIELD_TYPE.setOmitNorms(true);
|
||||||
|
FIELD_TYPE.setIndexAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setNames(new MappedFieldType.Names(NAME));
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +94,8 @@ public class IdFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
private String path = Defaults.PATH;
|
private String path = Defaults.PATH;
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
super(Defaults.NAME, new FieldType(Defaults.FIELD_TYPE));
|
super(Defaults.NAME, Defaults.FIELD_TYPE);
|
||||||
indexName = Defaults.INDEX_NAME;
|
indexName = Defaults.NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder path(String path) {
|
public Builder path(String path) {
|
||||||
|
@ -108,7 +110,8 @@ public class IdFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IdFieldMapper build(BuilderContext context) {
|
public IdFieldMapper build(BuilderContext context) {
|
||||||
return new IdFieldMapper(name, indexName, boost, fieldType, docValues, path, fieldDataSettings, context.indexSettings());
|
fieldType.setNames(new MappedFieldType.Names(name, indexName, indexName, name));
|
||||||
|
return new IdFieldMapper(fieldType, docValues, path, fieldDataSettings, context.indexSettings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,21 +136,109 @@ public class IdFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class IdFieldType extends MappedFieldType {
|
||||||
|
|
||||||
|
public IdFieldType() {
|
||||||
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IdFieldType(IdFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new IdFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useTermQueryWithQueryString() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query termQuery(Object value, @Nullable QueryParseContext context) {
|
||||||
|
if (indexOptions() != IndexOptions.NONE || context == null) {
|
||||||
|
return super.termQuery(value, context);
|
||||||
|
}
|
||||||
|
final BytesRef[] uids = Uid.createUidsForTypesAndId(context.queryTypes(), value);
|
||||||
|
return new TermsQuery(UidFieldMapper.NAME, uids);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query termsQuery(List values, @Nullable QueryParseContext context) {
|
||||||
|
if (indexOptions() != IndexOptions.NONE || context == null) {
|
||||||
|
return super.termsQuery(values, context);
|
||||||
|
}
|
||||||
|
return new TermsQuery(UidFieldMapper.NAME, Uid.createUidsForTypesAndIds(context.queryTypes(), values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query prefixQuery(Object value, @Nullable MultiTermQuery.RewriteMethod method, @Nullable QueryParseContext context) {
|
||||||
|
if (indexOptions() != IndexOptions.NONE || context == null) {
|
||||||
|
return super.prefixQuery(value, method, context);
|
||||||
|
}
|
||||||
|
Collection<String> queryTypes = context.queryTypes();
|
||||||
|
BooleanQuery query = new BooleanQuery();
|
||||||
|
for (String queryType : queryTypes) {
|
||||||
|
PrefixQuery prefixQuery = new PrefixQuery(new Term(UidFieldMapper.NAME, Uid.createUidAsBytes(queryType, BytesRefs.toBytesRef(value))));
|
||||||
|
if (method != null) {
|
||||||
|
prefixQuery.setRewriteMethod(method);
|
||||||
|
}
|
||||||
|
query.add(prefixQuery, BooleanClause.Occur.SHOULD);
|
||||||
|
}
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query regexpQuery(Object value, int flags, int maxDeterminizedStates, @Nullable MultiTermQuery.RewriteMethod method, @Nullable QueryParseContext context) {
|
||||||
|
if (indexOptions() != IndexOptions.NONE || context == null) {
|
||||||
|
return super.regexpQuery(value, flags, maxDeterminizedStates, method, context);
|
||||||
|
}
|
||||||
|
Collection<String> queryTypes = context.queryTypes();
|
||||||
|
if (queryTypes.size() == 1) {
|
||||||
|
RegexpQuery regexpQuery = new RegexpQuery(new Term(UidFieldMapper.NAME, Uid.createUidAsBytes(Iterables.getFirst(queryTypes, null), BytesRefs.toBytesRef(value))),
|
||||||
|
flags, maxDeterminizedStates);
|
||||||
|
if (method != null) {
|
||||||
|
regexpQuery.setRewriteMethod(method);
|
||||||
|
}
|
||||||
|
return regexpQuery;
|
||||||
|
}
|
||||||
|
BooleanQuery query = new BooleanQuery();
|
||||||
|
for (String queryType : queryTypes) {
|
||||||
|
RegexpQuery regexpQuery = new RegexpQuery(new Term(UidFieldMapper.NAME, Uid.createUidAsBytes(queryType, BytesRefs.toBytesRef(value))), flags, maxDeterminizedStates);
|
||||||
|
if (method != null) {
|
||||||
|
regexpQuery.setRewriteMethod(method);
|
||||||
|
}
|
||||||
|
query.add(regexpQuery, BooleanClause.Occur.SHOULD);
|
||||||
|
}
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final String path;
|
private final String path;
|
||||||
|
|
||||||
public IdFieldMapper(Settings indexSettings) {
|
public IdFieldMapper(Settings indexSettings) {
|
||||||
this(Defaults.NAME, Defaults.INDEX_NAME, Defaults.BOOST, idFieldType(indexSettings), null, Defaults.PATH, null, indexSettings);
|
this(idFieldType(indexSettings), null, Defaults.PATH, null, indexSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IdFieldMapper(String name, String indexName, float boost, FieldType fieldType, Boolean docValues, String path,
|
protected IdFieldMapper(MappedFieldType fieldType, Boolean docValues, String path,
|
||||||
@Nullable Settings fieldDataSettings, Settings indexSettings) {
|
@Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||||
super(new Names(name, indexName, indexName, name), boost, fieldType, docValues, Lucene.KEYWORD_ANALYZER,
|
super(fieldType, docValues, fieldDataSettings, indexSettings);
|
||||||
Lucene.KEYWORD_ANALYZER, null, null, fieldDataSettings, indexSettings);
|
|
||||||
this.path = path;
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FieldType idFieldType(Settings indexSettings) {
|
private static MappedFieldType idFieldType(Settings indexSettings) {
|
||||||
FieldType fieldType = new FieldType(Defaults.FIELD_TYPE);
|
MappedFieldType fieldType = Defaults.FIELD_TYPE.clone();
|
||||||
boolean pre2x = Version.indexCreated(indexSettings).before(Version.V_2_0_0);
|
boolean pre2x = Version.indexCreated(indexSettings).before(Version.V_2_0_0);
|
||||||
if (pre2x && indexSettings.getAsBoolean("index.mapping._id.indexed", true) == false) {
|
if (pre2x && indexSettings.getAsBoolean("index.mapping._id.indexed", true) == false) {
|
||||||
fieldType.setTokenized(false);
|
fieldType.setTokenized(false);
|
||||||
|
@ -160,7 +251,7 @@ public class IdFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,78 +260,6 @@ public class IdFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
return new FieldDataType("string");
|
return new FieldDataType("string");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean useTermQueryWithQueryString() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query termQuery(Object value, @Nullable QueryParseContext context) {
|
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || context == null) {
|
|
||||||
return super.termQuery(value, context);
|
|
||||||
}
|
|
||||||
final BytesRef[] uids = Uid.createUidsForTypesAndId(context.queryTypes(), value);
|
|
||||||
return new TermsQuery(UidFieldMapper.NAME, uids);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query termsQuery(List values, @Nullable QueryParseContext context) {
|
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || context == null) {
|
|
||||||
return super.termsQuery(values, context);
|
|
||||||
}
|
|
||||||
return new TermsQuery(UidFieldMapper.NAME, Uid.createUidsForTypesAndIds(context.queryTypes(), values));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query prefixQuery(Object value, @Nullable MultiTermQuery.RewriteMethod method, @Nullable QueryParseContext context) {
|
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || context == null) {
|
|
||||||
return super.prefixQuery(value, method, context);
|
|
||||||
}
|
|
||||||
Collection<String> queryTypes = context.queryTypes();
|
|
||||||
BooleanQuery query = new BooleanQuery();
|
|
||||||
for (String queryType : queryTypes) {
|
|
||||||
PrefixQuery prefixQuery = new PrefixQuery(new Term(UidFieldMapper.NAME, Uid.createUidAsBytes(queryType, BytesRefs.toBytesRef(value))));
|
|
||||||
if (method != null) {
|
|
||||||
prefixQuery.setRewriteMethod(method);
|
|
||||||
}
|
|
||||||
query.add(prefixQuery, BooleanClause.Occur.SHOULD);
|
|
||||||
}
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query regexpQuery(Object value, int flags, int maxDeterminizedStates, @Nullable MultiTermQuery.RewriteMethod method, @Nullable QueryParseContext context) {
|
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || context == null) {
|
|
||||||
return super.regexpQuery(value, flags, maxDeterminizedStates, method, context);
|
|
||||||
}
|
|
||||||
Collection<String> queryTypes = context.queryTypes();
|
|
||||||
if (queryTypes.size() == 1) {
|
|
||||||
RegexpQuery regexpQuery = new RegexpQuery(new Term(UidFieldMapper.NAME, Uid.createUidAsBytes(Iterables.getFirst(queryTypes, null), BytesRefs.toBytesRef(value))),
|
|
||||||
flags, maxDeterminizedStates);
|
|
||||||
if (method != null) {
|
|
||||||
regexpQuery.setRewriteMethod(method);
|
|
||||||
}
|
|
||||||
return regexpQuery;
|
|
||||||
}
|
|
||||||
BooleanQuery query = new BooleanQuery();
|
|
||||||
for (String queryType : queryTypes) {
|
|
||||||
RegexpQuery regexpQuery = new RegexpQuery(new Term(UidFieldMapper.NAME, Uid.createUidAsBytes(queryType, BytesRefs.toBytesRef(value))), flags, maxDeterminizedStates);
|
|
||||||
if (method != null) {
|
|
||||||
regexpQuery.setRewriteMethod(method);
|
|
||||||
}
|
|
||||||
query.add(regexpQuery, BooleanClause.Occur.SHOULD);
|
|
||||||
}
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preParse(ParseContext context) throws IOException {
|
public void preParse(ParseContext context) throws IOException {
|
||||||
if (context.sourceToParse().id() != null) {
|
if (context.sourceToParse().id() != null) {
|
||||||
|
@ -270,10 +289,10 @@ public class IdFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
} // else we are in the pre/post parse phase
|
} // else we are in the pre/post parse phase
|
||||||
|
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
||||||
fields.add(new Field(names.indexName(), context.id(), fieldType));
|
fields.add(new Field(fieldType.names().indexName(), context.id(), fieldType));
|
||||||
}
|
}
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
fields.add(new BinaryDocValuesField(names.indexName(), new BytesRef(context.id())));
|
fields.add(new BinaryDocValuesField(fieldType.names().indexName(), new BytesRef(context.id())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,7 +329,7 @@ public class IdFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
if (customFieldDataSettings != null) {
|
if (customFieldDataSettings != null) {
|
||||||
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
||||||
} else if (includeDefaults) {
|
} else if (includeDefaults) {
|
||||||
builder.field("fielddata", (Map) fieldDataType.getSettings().getAsMap());
|
builder.field("fielddata", (Map) fieldType.fieldDataType().getSettings().getAsMap());
|
||||||
}
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
return builder;
|
return builder;
|
||||||
|
|
|
@ -21,7 +21,6 @@ package org.elasticsearch.index.mapper.internal;
|
||||||
|
|
||||||
import org.apache.lucene.document.Document;
|
import org.apache.lucene.document.Document;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
|
@ -30,6 +29,7 @@ import org.elasticsearch.common.lucene.Lucene;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperBuilders;
|
import org.elasticsearch.index.mapper.MapperBuilders;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
|
@ -38,6 +38,7 @@ import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.mapper.RootMapper;
|
import org.elasticsearch.index.mapper.RootMapper;
|
||||||
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
|
||||||
|
import org.elasticsearch.search.highlight.HighlightBuilder;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -59,13 +60,16 @@ public class IndexFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
public static class Defaults extends AbstractFieldMapper.Defaults {
|
public static class Defaults extends AbstractFieldMapper.Defaults {
|
||||||
public static final String NAME = IndexFieldMapper.NAME;
|
public static final String NAME = IndexFieldMapper.NAME;
|
||||||
|
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new IndexFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
||||||
FIELD_TYPE.setTokenized(false);
|
FIELD_TYPE.setTokenized(false);
|
||||||
FIELD_TYPE.setStored(false);
|
FIELD_TYPE.setStored(false);
|
||||||
FIELD_TYPE.setOmitNorms(true);
|
FIELD_TYPE.setOmitNorms(true);
|
||||||
|
FIELD_TYPE.setIndexAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setNames(new MappedFieldType.Names(NAME));
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +81,7 @@ public class IndexFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
private EnabledAttributeMapper enabledState = EnabledAttributeMapper.UNSET_DISABLED;
|
private EnabledAttributeMapper enabledState = EnabledAttributeMapper.UNSET_DISABLED;
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
super(Defaults.NAME, new FieldType(Defaults.FIELD_TYPE));
|
super(Defaults.NAME, Defaults.FIELD_TYPE);
|
||||||
indexName = Defaults.NAME;
|
indexName = Defaults.NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +92,8 @@ public class IndexFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IndexFieldMapper build(BuilderContext context) {
|
public IndexFieldMapper build(BuilderContext context) {
|
||||||
return new IndexFieldMapper(name, indexName, boost, fieldType, enabledState, fieldDataSettings, context.indexSettings());
|
fieldType.setNames(new MappedFieldType.Names(name, indexName, indexName, name));
|
||||||
|
return new IndexFieldMapper(fieldType, enabledState, fieldDataSettings, context.indexSettings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,16 +119,39 @@ public class IndexFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class IndexFieldType extends MappedFieldType {
|
||||||
|
|
||||||
|
public IndexFieldType() {
|
||||||
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IndexFieldType(IndexFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new IndexFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private EnabledAttributeMapper enabledState;
|
private EnabledAttributeMapper enabledState;
|
||||||
|
|
||||||
public IndexFieldMapper(Settings indexSettings) {
|
public IndexFieldMapper(Settings indexSettings) {
|
||||||
this(Defaults.NAME, Defaults.NAME, Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), Defaults.ENABLED_STATE, null, indexSettings);
|
this(Defaults.FIELD_TYPE.clone(), Defaults.ENABLED_STATE, null, indexSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IndexFieldMapper(String name, String indexName, float boost, FieldType fieldType, EnabledAttributeMapper enabledState,
|
public IndexFieldMapper(MappedFieldType fieldType, EnabledAttributeMapper enabledState,
|
||||||
@Nullable Settings fieldDataSettings, Settings indexSettings) {
|
@Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||||
super(new Names(name, indexName, indexName, name), boost, fieldType, false, Lucene.KEYWORD_ANALYZER,
|
super(fieldType, false, fieldDataSettings, indexSettings);
|
||||||
Lucene.KEYWORD_ANALYZER, null, null, fieldDataSettings, indexSettings);
|
|
||||||
this.enabledState = enabledState;
|
this.enabledState = enabledState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +160,7 @@ public class IndexFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,16 +170,8 @@ public class IndexFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
}
|
}
|
||||||
|
|
||||||
public String value(Document document) {
|
public String value(Document document) {
|
||||||
Field field = (Field) document.getField(names.indexName());
|
Field field = (Field) document.getField(fieldType.names().indexName());
|
||||||
return field == null ? null : value(field);
|
return field == null ? null : (String)fieldType().value(field);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return value.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -174,7 +194,7 @@ public class IndexFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
if (!enabledState.enabled) {
|
if (!enabledState.enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fields.add(new Field(names.indexName(), context.index(), fieldType));
|
fields.add(new Field(fieldType.names().indexName(), context.index(), fieldType));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -202,7 +222,7 @@ public class IndexFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
if (customFieldDataSettings != null) {
|
if (customFieldDataSettings != null) {
|
||||||
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
||||||
} else if (includeDefaults) {
|
} else if (includeDefaults) {
|
||||||
builder.field("fielddata", (Map) fieldDataType.getSettings().getAsMap());
|
builder.field("fielddata", (Map) fieldType.fieldDataType().getSettings().getAsMap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
|
|
|
@ -20,7 +20,6 @@ package org.elasticsearch.index.mapper.internal;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.queries.TermsQuery;
|
import org.apache.lucene.queries.TermsQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
|
@ -35,6 +34,7 @@ import org.elasticsearch.common.settings.loader.SettingsLoader;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -70,18 +70,21 @@ public class ParentFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
public static class Defaults extends AbstractFieldMapper.Defaults {
|
public static class Defaults extends AbstractFieldMapper.Defaults {
|
||||||
public static final String NAME = ParentFieldMapper.NAME;
|
public static final String NAME = ParentFieldMapper.NAME;
|
||||||
|
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new ParentFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
||||||
FIELD_TYPE.setTokenized(false);
|
FIELD_TYPE.setTokenized(false);
|
||||||
FIELD_TYPE.setStored(true);
|
FIELD_TYPE.setStored(true);
|
||||||
FIELD_TYPE.setOmitNorms(true);
|
FIELD_TYPE.setOmitNorms(true);
|
||||||
|
FIELD_TYPE.setIndexAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setNames(new MappedFieldType.Names(NAME));
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder extends Mapper.Builder<Builder, ParentFieldMapper> {
|
public static class Builder extends AbstractFieldMapper.Builder<Builder, ParentFieldMapper> {
|
||||||
|
|
||||||
protected String indexName;
|
protected String indexName;
|
||||||
|
|
||||||
|
@ -89,7 +92,7 @@ public class ParentFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
protected Settings fieldDataSettings;
|
protected Settings fieldDataSettings;
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
super(Defaults.NAME);
|
super(Defaults.NAME, Defaults.FIELD_TYPE);
|
||||||
this.indexName = name;
|
this.indexName = name;
|
||||||
builder = this;
|
builder = this;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +112,8 @@ public class ParentFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
throw new MapperParsingException("Parent mapping must contain the parent type");
|
throw new MapperParsingException("Parent mapping must contain the parent type");
|
||||||
}
|
}
|
||||||
return new ParentFieldMapper(name, indexName, type, fieldDataSettings, context.indexSettings());
|
fieldType.setNames(new MappedFieldType.Names(name, indexName, indexName, name));
|
||||||
|
return new ParentFieldMapper(fieldType, type, fieldDataSettings, context.indexSettings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,8 +134,8 @@ public class ParentFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
} else if (fieldName.equals("fielddata")) {
|
} else if (fieldName.equals("fielddata")) {
|
||||||
// Only take over `loading`, since that is the only option now that is configurable:
|
// Only take over `loading`, since that is the only option now that is configurable:
|
||||||
Map<String, String> fieldDataSettings = SettingsLoader.Helper.loadNestedFromMap(nodeMapValue(fieldNode, "fielddata"));
|
Map<String, String> fieldDataSettings = SettingsLoader.Helper.loadNestedFromMap(nodeMapValue(fieldNode, "fielddata"));
|
||||||
if (fieldDataSettings.containsKey(Loading.KEY)) {
|
if (fieldDataSettings.containsKey(MappedFieldType.Loading.KEY)) {
|
||||||
Settings settings = settingsBuilder().put(Loading.KEY, fieldDataSettings.get(Loading.KEY)).build();
|
Settings settings = settingsBuilder().put(MappedFieldType.Loading.KEY, fieldDataSettings.get(MappedFieldType.Loading.KEY)).build();
|
||||||
builder.fieldDataSettings(settings);
|
builder.fieldDataSettings(settings);
|
||||||
}
|
}
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
|
@ -141,19 +145,101 @@ public class ParentFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ParentFieldType extends MappedFieldType {
|
||||||
|
|
||||||
|
public ParentFieldType() {
|
||||||
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ParentFieldType(ParentFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new ParentFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Uid value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Uid.createUid(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object valueForSearch(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String sValue = value.toString();
|
||||||
|
if (sValue == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int index = sValue.indexOf(Uid.DELIMITER);
|
||||||
|
if (index == -1) {
|
||||||
|
return sValue;
|
||||||
|
}
|
||||||
|
return sValue.substring(index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We don't need to analyzer the text, and we need to convert it to UID...
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean useTermQueryWithQueryString() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query termQuery(Object value, @Nullable QueryParseContext context) {
|
||||||
|
return termsQuery(Collections.singletonList(value), context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query termsQuery(List values, @Nullable QueryParseContext context) {
|
||||||
|
if (context == null) {
|
||||||
|
return super.termsQuery(values, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> types = new ArrayList<>(context.mapperService().types().size());
|
||||||
|
for (DocumentMapper documentMapper : context.mapperService().docMappers(false)) {
|
||||||
|
if (!documentMapper.parentFieldMapper().active()) {
|
||||||
|
types.add(documentMapper.type());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<BytesRef> bValues = new ArrayList<>(values.size());
|
||||||
|
for (Object value : values) {
|
||||||
|
BytesRef bValue = BytesRefs.toBytesRef(value);
|
||||||
|
if (Uid.hasDelimiter(bValue)) {
|
||||||
|
bValues.add(bValue);
|
||||||
|
} else {
|
||||||
|
// we use all non child types, cause we don't know if its exact or not...
|
||||||
|
for (String type : types) {
|
||||||
|
bValues.add(Uid.createUidAsBytes(type, bValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new TermsQuery(names().indexName(), bValues);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final String type;
|
private final String type;
|
||||||
private final BytesRef typeAsBytes;
|
private final BytesRef typeAsBytes;
|
||||||
|
|
||||||
protected ParentFieldMapper(String name, String indexName, String type, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
protected ParentFieldMapper(MappedFieldType fieldType, String type, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||||
super(new Names(name, indexName, indexName, name), Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), false,
|
super(fieldType, false, fieldDataSettings, indexSettings);
|
||||||
Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER, null, null, fieldDataSettings, indexSettings);
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.typeAsBytes = type == null ? null : new BytesRef(type);
|
this.typeAsBytes = type == null ? null : new BytesRef(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParentFieldMapper(Settings indexSettings) {
|
public ParentFieldMapper(Settings indexSettings) {
|
||||||
this(Defaults.NAME, Defaults.NAME, null, null, indexSettings);
|
this(Defaults.FIELD_TYPE.clone(), null, null, indexSettings);
|
||||||
this.fieldDataType = new FieldDataType("_parent", settingsBuilder().put(Loading.KEY, Loading.LAZY_VALUE));
|
this.fieldType = this.fieldType.clone();
|
||||||
|
this.fieldType.setFieldDataType(new FieldDataType("_parent", settingsBuilder().put(MappedFieldType.Loading.KEY, MappedFieldType.Loading.LAZY_VALUE)));
|
||||||
|
this.fieldType.freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String type() {
|
public String type() {
|
||||||
|
@ -161,13 +247,13 @@ public class ParentFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldDataType defaultFieldDataType() {
|
public FieldDataType defaultFieldDataType() {
|
||||||
return new FieldDataType("_parent", settingsBuilder().put(Loading.KEY, Loading.EAGER_VALUE));
|
return new FieldDataType("_parent", settingsBuilder().put(MappedFieldType.Loading.KEY, MappedFieldType.Loading.EAGER_VALUE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -189,7 +275,7 @@ public class ParentFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
// we are in the parsing of _parent phase
|
// we are in the parsing of _parent phase
|
||||||
String parentId = context.parser().text();
|
String parentId = context.parser().text();
|
||||||
context.sourceToParse().parent(parentId);
|
context.sourceToParse().parent(parentId);
|
||||||
fields.add(new Field(names.indexName(), Uid.createUid(context.stringBuilder(), type, parentId), fieldType));
|
fields.add(new Field(fieldType.names().indexName(), Uid.createUid(context.stringBuilder(), type, parentId), fieldType));
|
||||||
} else {
|
} else {
|
||||||
// otherwise, we are running it post processing of the xcontent
|
// otherwise, we are running it post processing of the xcontent
|
||||||
String parsedParentId = context.doc().get(Defaults.NAME);
|
String parsedParentId = context.doc().get(Defaults.NAME);
|
||||||
|
@ -200,7 +286,7 @@ public class ParentFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
throw new MapperParsingException("No parent id provided, not within the document, and not externally");
|
throw new MapperParsingException("No parent id provided, not within the document, and not externally");
|
||||||
}
|
}
|
||||||
// we did not add it in the parsing phase, add it now
|
// we did not add it in the parsing phase, add it now
|
||||||
fields.add(new Field(names.indexName(), Uid.createUid(context.stringBuilder(), type, parentId), fieldType));
|
fields.add(new Field(fieldType.names().indexName(), Uid.createUid(context.stringBuilder(), type, parentId), fieldType));
|
||||||
} else if (parentId != null && !parsedParentId.equals(Uid.createUid(context.stringBuilder(), type, parentId))) {
|
} else if (parentId != null && !parsedParentId.equals(Uid.createUid(context.stringBuilder(), type, parentId))) {
|
||||||
throw new MapperParsingException("Parent id mismatch, document value is [" + Uid.createUid(parsedParentId).id() + "], while external value is [" + parentId + "]");
|
throw new MapperParsingException("Parent id mismatch, document value is [" + Uid.createUid(parsedParentId).id() + "], while external value is [" + parentId + "]");
|
||||||
}
|
}
|
||||||
|
@ -209,87 +295,6 @@ public class ParentFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
// we have parent mapping, yet no value was set, ignore it...
|
// we have parent mapping, yet no value was set, ignore it...
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Uid value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return Uid.createUid(value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object valueForSearch(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String sValue = value.toString();
|
|
||||||
if (sValue == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
int index = sValue.indexOf(Uid.DELIMITER);
|
|
||||||
if (index == -1) {
|
|
||||||
return sValue;
|
|
||||||
}
|
|
||||||
return sValue.substring(index + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BytesRef indexedValueForSearch(Object value) {
|
|
||||||
if (value instanceof BytesRef) {
|
|
||||||
BytesRef bytesRef = (BytesRef) value;
|
|
||||||
if (Uid.hasDelimiter(bytesRef)) {
|
|
||||||
return bytesRef;
|
|
||||||
}
|
|
||||||
return Uid.createUidAsBytes(typeAsBytes, bytesRef);
|
|
||||||
}
|
|
||||||
String sValue = value.toString();
|
|
||||||
if (sValue.indexOf(Uid.DELIMITER) == -1) {
|
|
||||||
return Uid.createUidAsBytes(type, sValue);
|
|
||||||
}
|
|
||||||
return super.indexedValueForSearch(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query termQuery(Object value, @Nullable QueryParseContext context) {
|
|
||||||
return termsQuery(Collections.singletonList(value), context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query termsQuery(List values, @Nullable QueryParseContext context) {
|
|
||||||
if (context == null) {
|
|
||||||
return super.termsQuery(values, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> types = new ArrayList<>(context.mapperService().types().size());
|
|
||||||
for (DocumentMapper documentMapper : context.mapperService().docMappers(false)) {
|
|
||||||
if (!documentMapper.parentFieldMapper().active()) {
|
|
||||||
types.add(documentMapper.type());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<BytesRef> bValues = new ArrayList<>(values.size());
|
|
||||||
for (Object value : values) {
|
|
||||||
BytesRef bValue = BytesRefs.toBytesRef(value);
|
|
||||||
if (Uid.hasDelimiter(bValue)) {
|
|
||||||
bValues.add(bValue);
|
|
||||||
} else {
|
|
||||||
// we use all non child types, cause we don't know if its exact or not...
|
|
||||||
for (String type : types) {
|
|
||||||
bValues.add(Uid.createUidAsBytes(type, bValue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new TermsQuery(names.indexName(), bValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We don't need to analyzer the text, and we need to convert it to UID...
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean useTermQueryWithQueryString() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String contentType() {
|
protected String contentType() {
|
||||||
return CONTENT_TYPE;
|
return CONTENT_TYPE;
|
||||||
|
@ -307,12 +312,28 @@ public class ParentFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
if (customFieldDataSettings != null) {
|
if (customFieldDataSettings != null) {
|
||||||
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
||||||
} else if (includeDefaults) {
|
} else if (includeDefaults) {
|
||||||
builder.field("fielddata", (Map) fieldDataType.getSettings().getAsMap());
|
builder.field("fielddata", (Map) fieldType.fieldDataType().getSettings().getAsMap());
|
||||||
}
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BytesRef indexedValueForSearch(Object value) {
|
||||||
|
if (value instanceof BytesRef) {
|
||||||
|
BytesRef bytesRef = (BytesRef) value;
|
||||||
|
if (Uid.hasDelimiter(bytesRef)) {
|
||||||
|
return bytesRef;
|
||||||
|
}
|
||||||
|
return Uid.createUidAsBytes(typeAsBytes, bytesRef);
|
||||||
|
}
|
||||||
|
String sValue = value.toString();
|
||||||
|
if (sValue.indexOf(Uid.DELIMITER) == -1) {
|
||||||
|
return Uid.createUidAsBytes(type, sValue);
|
||||||
|
}
|
||||||
|
return super.indexedValueForSearch(value);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void merge(Mapper mergeWith, MergeResult mergeResult) throws MergeMappingException {
|
public void merge(Mapper mergeWith, MergeResult mergeResult) throws MergeMappingException {
|
||||||
ParentFieldMapper other = (ParentFieldMapper) mergeWith;
|
ParentFieldMapper other = (ParentFieldMapper) mergeWith;
|
||||||
|
@ -322,14 +343,16 @@ public class ParentFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
|
|
||||||
if (!mergeResult.simulate()) {
|
if (!mergeResult.simulate()) {
|
||||||
ParentFieldMapper fieldMergeWith = (ParentFieldMapper) mergeWith;
|
ParentFieldMapper fieldMergeWith = (ParentFieldMapper) mergeWith;
|
||||||
|
this.fieldType = this.fieldType.clone();
|
||||||
if (fieldMergeWith.customFieldDataSettings != null) {
|
if (fieldMergeWith.customFieldDataSettings != null) {
|
||||||
if (!Objects.equal(fieldMergeWith.customFieldDataSettings, this.customFieldDataSettings)) {
|
if (!Objects.equal(fieldMergeWith.customFieldDataSettings, this.customFieldDataSettings)) {
|
||||||
this.customFieldDataSettings = fieldMergeWith.customFieldDataSettings;
|
this.customFieldDataSettings = fieldMergeWith.customFieldDataSettings;
|
||||||
this.fieldDataType = new FieldDataType(defaultFieldDataType().getType(),
|
this.fieldType.setFieldDataType(new FieldDataType(defaultFieldDataType().getType(),
|
||||||
builder().put(defaultFieldDataType().getSettings()).put(this.customFieldDataSettings)
|
builder().put(defaultFieldDataType().getSettings()).put(this.customFieldDataSettings)
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.fieldType.freeze();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ package org.elasticsearch.index.mapper.internal;
|
||||||
|
|
||||||
import org.apache.lucene.document.Document;
|
import org.apache.lucene.document.Document;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
|
@ -30,6 +29,7 @@ import org.elasticsearch.common.lucene.Lucene;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -58,13 +58,16 @@ public class RoutingFieldMapper extends AbstractFieldMapper implements RootMappe
|
||||||
public static class Defaults extends AbstractFieldMapper.Defaults {
|
public static class Defaults extends AbstractFieldMapper.Defaults {
|
||||||
public static final String NAME = "_routing";
|
public static final String NAME = "_routing";
|
||||||
|
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new RoutingFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
||||||
FIELD_TYPE.setTokenized(false);
|
FIELD_TYPE.setTokenized(false);
|
||||||
FIELD_TYPE.setStored(true);
|
FIELD_TYPE.setStored(true);
|
||||||
FIELD_TYPE.setOmitNorms(true);
|
FIELD_TYPE.setOmitNorms(true);
|
||||||
|
FIELD_TYPE.setIndexAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setNames(new MappedFieldType.Names(NAME));
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +82,7 @@ public class RoutingFieldMapper extends AbstractFieldMapper implements RootMappe
|
||||||
private String path = Defaults.PATH;
|
private String path = Defaults.PATH;
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
super(Defaults.NAME, new FieldType(Defaults.FIELD_TYPE));
|
super(Defaults.NAME, Defaults.FIELD_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder required(boolean required) {
|
public Builder required(boolean required) {
|
||||||
|
@ -121,6 +124,29 @@ public class RoutingFieldMapper extends AbstractFieldMapper implements RootMappe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class RoutingFieldType extends MappedFieldType {
|
||||||
|
|
||||||
|
public RoutingFieldType() {
|
||||||
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RoutingFieldType(RoutingFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new RoutingFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean required;
|
private boolean required;
|
||||||
private final String path;
|
private final String path;
|
||||||
|
@ -129,15 +155,14 @@ public class RoutingFieldMapper extends AbstractFieldMapper implements RootMappe
|
||||||
this(Defaults.FIELD_TYPE, Defaults.REQUIRED, Defaults.PATH, null, indexSettings);
|
this(Defaults.FIELD_TYPE, Defaults.REQUIRED, Defaults.PATH, null, indexSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RoutingFieldMapper(FieldType fieldType, boolean required, String path, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
protected RoutingFieldMapper(MappedFieldType fieldType, boolean required, String path, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||||
super(new Names(Defaults.NAME, Defaults.NAME, Defaults.NAME, Defaults.NAME), 1.0f, fieldType, false, Lucene.KEYWORD_ANALYZER,
|
super(fieldType, false, fieldDataSettings, indexSettings);
|
||||||
Lucene.KEYWORD_ANALYZER, null, null, fieldDataSettings, indexSettings);
|
|
||||||
this.required = required;
|
this.required = required;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,16 +184,8 @@ public class RoutingFieldMapper extends AbstractFieldMapper implements RootMappe
|
||||||
}
|
}
|
||||||
|
|
||||||
public String value(Document document) {
|
public String value(Document document) {
|
||||||
Field field = (Field) document.getField(names.indexName());
|
Field field = (Field) document.getField(fieldType.names().indexName());
|
||||||
return field == null ? null : value(field);
|
return field == null ? null : (String)value(field);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return value.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -194,10 +211,10 @@ public class RoutingFieldMapper extends AbstractFieldMapper implements RootMappe
|
||||||
String routing = context.sourceToParse().routing();
|
String routing = context.sourceToParse().routing();
|
||||||
if (routing != null) {
|
if (routing != null) {
|
||||||
if (fieldType.indexOptions() == IndexOptions.NONE && !fieldType.stored()) {
|
if (fieldType.indexOptions() == IndexOptions.NONE && !fieldType.stored()) {
|
||||||
context.ignoredValue(names.indexName(), routing);
|
context.ignoredValue(fieldType.names().indexName(), routing);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fields.add(new Field(names.indexName(), routing, fieldType));
|
fields.add(new Field(fieldType.names().indexName(), routing, fieldType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,16 +20,18 @@
|
||||||
package org.elasticsearch.index.mapper.internal;
|
package org.elasticsearch.index.mapper.internal;
|
||||||
|
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
|
import org.elasticsearch.index.analysis.NumericIntegerAnalyzer;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeResult;
|
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
import org.elasticsearch.index.mapper.MergeResult;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.mapper.RootMapper;
|
import org.elasticsearch.index.mapper.RootMapper;
|
||||||
import org.elasticsearch.index.mapper.core.IntegerFieldMapper;
|
import org.elasticsearch.index.mapper.core.IntegerFieldMapper;
|
||||||
|
@ -53,10 +55,12 @@ public class SizeFieldMapper extends IntegerFieldMapper implements RootMapper {
|
||||||
public static final String NAME = CONTENT_TYPE;
|
public static final String NAME = CONTENT_TYPE;
|
||||||
public static final EnabledAttributeMapper ENABLED_STATE = EnabledAttributeMapper.UNSET_DISABLED;
|
public static final EnabledAttributeMapper ENABLED_STATE = EnabledAttributeMapper.UNSET_DISABLED;
|
||||||
|
|
||||||
public static final FieldType SIZE_FIELD_TYPE = new FieldType(IntegerFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType SIZE_FIELD_TYPE = IntegerFieldMapper.Defaults.FIELD_TYPE.clone();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
SIZE_FIELD_TYPE.setStored(true);
|
SIZE_FIELD_TYPE.setStored(true);
|
||||||
|
SIZE_FIELD_TYPE.setNumericPrecisionStep(Defaults.PRECISION_STEP_32_BIT);
|
||||||
|
SIZE_FIELD_TYPE.setNames(new MappedFieldType.Names(NAME));
|
||||||
SIZE_FIELD_TYPE.freeze();
|
SIZE_FIELD_TYPE.freeze();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +70,7 @@ public class SizeFieldMapper extends IntegerFieldMapper implements RootMapper {
|
||||||
protected EnabledAttributeMapper enabledState = EnabledAttributeMapper.UNSET_DISABLED;
|
protected EnabledAttributeMapper enabledState = EnabledAttributeMapper.UNSET_DISABLED;
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
super(Defaults.NAME, new FieldType(Defaults.SIZE_FIELD_TYPE), Defaults.PRECISION_STEP_32_BIT);
|
super(Defaults.NAME, Defaults.SIZE_FIELD_TYPE, Defaults.PRECISION_STEP_32_BIT);
|
||||||
builder = this;
|
builder = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,8 +81,19 @@ public class SizeFieldMapper extends IntegerFieldMapper implements RootMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SizeFieldMapper build(BuilderContext context) {
|
public SizeFieldMapper build(BuilderContext context) {
|
||||||
|
setupFieldType(context);
|
||||||
return new SizeFieldMapper(enabledState, fieldType, fieldDataSettings, context.indexSettings());
|
return new SizeFieldMapper(enabledState, fieldType, fieldDataSettings, context.indexSettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NamedAnalyzer makeNumberAnalyzer(int precisionStep) {
|
||||||
|
return NumericIntegerAnalyzer.buildNamedAnalyzer(precisionStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int maxPrecisionStep() {
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TypeParser implements Mapper.TypeParser {
|
public static class TypeParser implements Mapper.TypeParser {
|
||||||
|
@ -104,12 +119,12 @@ public class SizeFieldMapper extends IntegerFieldMapper implements RootMapper {
|
||||||
private EnabledAttributeMapper enabledState;
|
private EnabledAttributeMapper enabledState;
|
||||||
|
|
||||||
public SizeFieldMapper(Settings indexSettings) {
|
public SizeFieldMapper(Settings indexSettings) {
|
||||||
this(Defaults.ENABLED_STATE, new FieldType(Defaults.SIZE_FIELD_TYPE), null, indexSettings);
|
this(Defaults.ENABLED_STATE, Defaults.SIZE_FIELD_TYPE.clone(), null, indexSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SizeFieldMapper(EnabledAttributeMapper enabled, FieldType fieldType, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
public SizeFieldMapper(EnabledAttributeMapper enabled, MappedFieldType fieldType, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||||
super(new Names(Defaults.NAME), Defaults.PRECISION_STEP_32_BIT, Defaults.BOOST, fieldType, false, Defaults.NULL_VALUE,
|
super(fieldType, false, Defaults.NULL_VALUE,
|
||||||
Defaults.IGNORE_MALFORMED, Defaults.COERCE, null, null, fieldDataSettings,
|
Defaults.IGNORE_MALFORMED, Defaults.COERCE, fieldDataSettings,
|
||||||
indexSettings, MultiFields.empty(), null);
|
indexSettings, MultiFields.empty(), null);
|
||||||
this.enabledState = enabled;
|
this.enabledState = enabled;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ package org.elasticsearch.index.mapper.internal;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.document.StoredField;
|
import org.apache.lucene.document.StoredField;
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
|
@ -45,6 +44,7 @@ import org.elasticsearch.common.xcontent.XContentHelper;
|
||||||
import org.elasticsearch.common.xcontent.XContentType;
|
import org.elasticsearch.common.xcontent.XContentType;
|
||||||
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -78,12 +78,15 @@ public class SourceFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
public static final long COMPRESS_THRESHOLD = -1;
|
public static final long COMPRESS_THRESHOLD = -1;
|
||||||
public static final String FORMAT = null; // default format is to use the one provided
|
public static final String FORMAT = null; // default format is to use the one provided
|
||||||
|
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new SourceFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setIndexOptions(IndexOptions.NONE); // not indexed
|
FIELD_TYPE.setIndexOptions(IndexOptions.NONE); // not indexed
|
||||||
FIELD_TYPE.setStored(true);
|
FIELD_TYPE.setStored(true);
|
||||||
FIELD_TYPE.setOmitNorms(true);
|
FIELD_TYPE.setOmitNorms(true);
|
||||||
|
FIELD_TYPE.setIndexAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setNames(new MappedFieldType.Names(NAME));
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +141,7 @@ public class SourceFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SourceFieldMapper build(BuilderContext context) {
|
public SourceFieldMapper build(BuilderContext context) {
|
||||||
return new SourceFieldMapper(name, enabled, format, compress, compressThreshold, includes, excludes, context.indexSettings());
|
return new SourceFieldMapper(enabled, format, compress, compressThreshold, includes, excludes, context.indexSettings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,6 +198,39 @@ public class SourceFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class SourceFieldType extends MappedFieldType {
|
||||||
|
|
||||||
|
public SourceFieldType() {
|
||||||
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SourceFieldType(SourceFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new SourceFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
BytesReference bValue;
|
||||||
|
if (value instanceof BytesRef) {
|
||||||
|
bValue = new BytesArray((BytesRef) value);
|
||||||
|
} else {
|
||||||
|
bValue = (BytesReference) value;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return CompressorFactory.uncompressIfNeeded(bValue).toBytes();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ElasticsearchParseException("failed to decompress source", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final boolean enabled;
|
private final boolean enabled;
|
||||||
|
|
||||||
|
@ -212,13 +248,12 @@ public class SourceFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
private XContentType formatContentType;
|
private XContentType formatContentType;
|
||||||
|
|
||||||
public SourceFieldMapper(Settings indexSettings) {
|
public SourceFieldMapper(Settings indexSettings) {
|
||||||
this(Defaults.NAME, Defaults.ENABLED, Defaults.FORMAT, null, -1, null, null, indexSettings);
|
this(Defaults.ENABLED, Defaults.FORMAT, null, -1, null, null, indexSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SourceFieldMapper(String name, boolean enabled, String format, Boolean compress, long compressThreshold,
|
protected SourceFieldMapper(boolean enabled, String format, Boolean compress, long compressThreshold,
|
||||||
String[] includes, String[] excludes, Settings indexSettings) {
|
String[] includes, String[] excludes, Settings indexSettings) {
|
||||||
super(new Names(name, name, name, name), Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), false,
|
super(Defaults.FIELD_TYPE.clone(), false, null, indexSettings); // Only stored.
|
||||||
Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER, null, null, null, indexSettings); // Only stored.
|
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
this.compress = compress;
|
this.compress = compress;
|
||||||
this.compressThreshold = compressThreshold;
|
this.compressThreshold = compressThreshold;
|
||||||
|
@ -247,7 +282,7 @@ public class SourceFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,25 +393,7 @@ public class SourceFieldMapper extends AbstractFieldMapper implements RootMapper
|
||||||
if (!source.hasArray()) {
|
if (!source.hasArray()) {
|
||||||
source = source.toBytesArray();
|
source = source.toBytesArray();
|
||||||
}
|
}
|
||||||
fields.add(new StoredField(names().indexName(), source.array(), source.arrayOffset(), source.length()));
|
fields.add(new StoredField(fieldType().names().indexName(), source.array(), source.arrayOffset(), source.length()));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
BytesReference bValue;
|
|
||||||
if (value instanceof BytesRef) {
|
|
||||||
bValue = new BytesArray((BytesRef) value);
|
|
||||||
} else {
|
|
||||||
bValue = (BytesReference) value;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return CompressorFactory.uncompressIfNeeded(bValue).toBytes();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new ElasticsearchParseException("failed to decompress source", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.index.mapper.internal;
|
package org.elasticsearch.index.mapper.internal;
|
||||||
|
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.elasticsearch.common.Explicit;
|
import org.elasticsearch.common.Explicit;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
|
@ -30,6 +29,9 @@ import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.index.AlreadyExpiredException;
|
import org.elasticsearch.index.AlreadyExpiredException;
|
||||||
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
|
import org.elasticsearch.index.analysis.NumericLongAnalyzer;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -59,12 +61,14 @@ public class TTLFieldMapper extends LongFieldMapper implements RootMapper {
|
||||||
public static class Defaults extends LongFieldMapper.Defaults {
|
public static class Defaults extends LongFieldMapper.Defaults {
|
||||||
public static final String NAME = TTLFieldMapper.CONTENT_TYPE;
|
public static final String NAME = TTLFieldMapper.CONTENT_TYPE;
|
||||||
|
|
||||||
public static final FieldType TTL_FIELD_TYPE = new FieldType(LongFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType TTL_FIELD_TYPE = new TTLFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
TTL_FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
TTL_FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
||||||
TTL_FIELD_TYPE.setStored(true);
|
TTL_FIELD_TYPE.setStored(true);
|
||||||
TTL_FIELD_TYPE.setTokenized(false);
|
TTL_FIELD_TYPE.setTokenized(false);
|
||||||
|
TTL_FIELD_TYPE.setNumericPrecisionStep(Defaults.PRECISION_STEP_64_BIT);
|
||||||
|
TTL_FIELD_TYPE.setNames(new MappedFieldType.Names(NAME));
|
||||||
TTL_FIELD_TYPE.freeze();
|
TTL_FIELD_TYPE.freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +82,7 @@ public class TTLFieldMapper extends LongFieldMapper implements RootMapper {
|
||||||
private long defaultTTL = Defaults.DEFAULT;
|
private long defaultTTL = Defaults.DEFAULT;
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
super(Defaults.NAME, new FieldType(Defaults.TTL_FIELD_TYPE), Defaults.PRECISION_STEP_64_BIT);
|
super(Defaults.NAME, Defaults.TTL_FIELD_TYPE, Defaults.PRECISION_STEP_64_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder enabled(EnabledAttributeMapper enabled) {
|
public Builder enabled(EnabledAttributeMapper enabled) {
|
||||||
|
@ -93,8 +97,19 @@ public class TTLFieldMapper extends LongFieldMapper implements RootMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TTLFieldMapper build(BuilderContext context) {
|
public TTLFieldMapper build(BuilderContext context) {
|
||||||
|
setupFieldType(context);
|
||||||
return new TTLFieldMapper(fieldType, enabledState, defaultTTL, ignoreMalformed(context),coerce(context), fieldDataSettings, context.indexSettings());
|
return new TTLFieldMapper(fieldType, enabledState, defaultTTL, ignoreMalformed(context),coerce(context), fieldDataSettings, context.indexSettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NamedAnalyzer makeNumberAnalyzer(int precisionStep) {
|
||||||
|
return NumericLongAnalyzer.buildNamedAnalyzer(precisionStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int maxPrecisionStep() {
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TypeParser implements Mapper.TypeParser {
|
public static class TypeParser implements Mapper.TypeParser {
|
||||||
|
@ -121,18 +136,46 @@ public class TTLFieldMapper extends LongFieldMapper implements RootMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class TTLFieldType extends LongFieldType {
|
||||||
|
|
||||||
|
public TTLFieldType() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TTLFieldType(TTLFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LongFieldType clone() {
|
||||||
|
return new TTLFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overrides valueForSearch to display live value of remaining ttl
|
||||||
|
@Override
|
||||||
|
public Object valueForSearch(Object value) {
|
||||||
|
long now;
|
||||||
|
SearchContext searchContext = SearchContext.current();
|
||||||
|
if (searchContext != null) {
|
||||||
|
now = searchContext.nowInMillis();
|
||||||
|
} else {
|
||||||
|
now = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
long val = value(value);
|
||||||
|
return val - now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private EnabledAttributeMapper enabledState;
|
private EnabledAttributeMapper enabledState;
|
||||||
private long defaultTTL;
|
private long defaultTTL;
|
||||||
|
|
||||||
public TTLFieldMapper(Settings indexSettings) {
|
public TTLFieldMapper(Settings indexSettings) {
|
||||||
this(new FieldType(Defaults.TTL_FIELD_TYPE), Defaults.ENABLED_STATE, Defaults.DEFAULT, Defaults.IGNORE_MALFORMED, Defaults.COERCE, null, indexSettings);
|
this(Defaults.TTL_FIELD_TYPE.clone(), Defaults.ENABLED_STATE, Defaults.DEFAULT, Defaults.IGNORE_MALFORMED, Defaults.COERCE, null, indexSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TTLFieldMapper(FieldType fieldType, EnabledAttributeMapper enabled, long defaultTTL, Explicit<Boolean> ignoreMalformed,
|
protected TTLFieldMapper(MappedFieldType fieldType, EnabledAttributeMapper enabled, long defaultTTL, Explicit<Boolean> ignoreMalformed,
|
||||||
Explicit<Boolean> coerce, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
Explicit<Boolean> coerce, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||||
super(new Names(Defaults.NAME, Defaults.NAME, Defaults.NAME, Defaults.NAME), Defaults.PRECISION_STEP_64_BIT,
|
super(fieldType, false, Defaults.NULL_VALUE, ignoreMalformed, coerce,
|
||||||
Defaults.BOOST, fieldType, false, Defaults.NULL_VALUE, ignoreMalformed, coerce,
|
fieldDataSettings, indexSettings, MultiFields.empty(), null);
|
||||||
null, null, fieldDataSettings, indexSettings, MultiFields.empty(), null);
|
|
||||||
this.enabledState = enabled;
|
this.enabledState = enabled;
|
||||||
this.defaultTTL = defaultTTL;
|
this.defaultTTL = defaultTTL;
|
||||||
}
|
}
|
||||||
|
@ -145,20 +188,6 @@ public class TTLFieldMapper extends LongFieldMapper implements RootMapper {
|
||||||
return this.defaultTTL;
|
return this.defaultTTL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overrides valueForSearch to display live value of remaining ttl
|
|
||||||
@Override
|
|
||||||
public Object valueForSearch(Object value) {
|
|
||||||
long now;
|
|
||||||
SearchContext searchContext = SearchContext.current();
|
|
||||||
if (searchContext != null) {
|
|
||||||
now = searchContext.nowInMillis();
|
|
||||||
} else {
|
|
||||||
now = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
long val = value(value);
|
|
||||||
return val - now;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Other implementation for realtime get display
|
// Other implementation for realtime get display
|
||||||
public Object valueForSearch(long expirationTime) {
|
public Object valueForSearch(long expirationTime) {
|
||||||
return expirationTime - System.currentTimeMillis();
|
return expirationTime - System.currentTimeMillis();
|
||||||
|
@ -207,7 +236,7 @@ public class TTLFieldMapper extends LongFieldMapper implements RootMapper {
|
||||||
throw new AlreadyExpiredException(context.index(), context.type(), context.id(), timestamp, ttl, now);
|
throw new AlreadyExpiredException(context.index(), context.type(), context.id(), timestamp, ttl, now);
|
||||||
}
|
}
|
||||||
// the expiration timestamp (timestamp + ttl) is set as field
|
// the expiration timestamp (timestamp + ttl) is set as field
|
||||||
fields.add(new CustomLongNumericField(this, expire, fieldType));
|
fields.add(new CustomLongNumericField(this, expire, (NumberFieldType)fieldType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.index.mapper.internal;
|
package org.elasticsearch.index.mapper.internal;
|
||||||
|
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.document.NumericDocValuesField;
|
import org.apache.lucene.document.NumericDocValuesField;
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
|
@ -32,6 +31,9 @@ import org.elasticsearch.common.joda.FormatDateTimeFormatter;
|
||||||
import org.elasticsearch.common.joda.Joda;
|
import org.elasticsearch.common.joda.Joda;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
|
import org.elasticsearch.index.analysis.NumericDateAnalyzer;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -46,7 +48,6 @@ import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue;
|
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue;
|
||||||
import static org.elasticsearch.index.mapper.MapperBuilders.timestamp;
|
import static org.elasticsearch.index.mapper.MapperBuilders.timestamp;
|
||||||
|
@ -63,21 +64,26 @@ public class TimestampFieldMapper extends DateFieldMapper implements RootMapper
|
||||||
public static final String NAME = "_timestamp";
|
public static final String NAME = "_timestamp";
|
||||||
|
|
||||||
// TODO: this should be removed
|
// TODO: this should be removed
|
||||||
public static final FieldType PRE_20_FIELD_TYPE;
|
public static final MappedFieldType PRE_20_FIELD_TYPE;
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(DateFieldMapper.Defaults.FIELD_TYPE);
|
public static final FormatDateTimeFormatter DATE_TIME_FORMATTER = Joda.forPattern(DEFAULT_DATE_TIME_FORMAT);
|
||||||
|
public static final DateFieldType FIELD_TYPE = new TimestampFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setStored(true);
|
FIELD_TYPE.setStored(true);
|
||||||
FIELD_TYPE.setTokenized(false);
|
FIELD_TYPE.setTokenized(false);
|
||||||
|
FIELD_TYPE.setNumericPrecisionStep(Defaults.PRECISION_STEP_64_BIT);
|
||||||
|
FIELD_TYPE.setNames(new MappedFieldType.Names(NAME));
|
||||||
|
FIELD_TYPE.setDateTimeFormatter(DATE_TIME_FORMATTER);
|
||||||
|
FIELD_TYPE.setIndexAnalyzer(NumericDateAnalyzer.buildNamedAnalyzer(DATE_TIME_FORMATTER, Defaults.PRECISION_STEP_64_BIT));
|
||||||
|
FIELD_TYPE.setSearchAnalyzer(NumericDateAnalyzer.buildNamedAnalyzer(DATE_TIME_FORMATTER, Integer.MAX_VALUE));
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
PRE_20_FIELD_TYPE = new FieldType(FIELD_TYPE);
|
PRE_20_FIELD_TYPE = FIELD_TYPE.clone();
|
||||||
PRE_20_FIELD_TYPE.setStored(false);
|
PRE_20_FIELD_TYPE.setStored(false);
|
||||||
PRE_20_FIELD_TYPE.freeze();
|
PRE_20_FIELD_TYPE.freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final EnabledAttributeMapper ENABLED = EnabledAttributeMapper.UNSET_DISABLED;
|
public static final EnabledAttributeMapper ENABLED = EnabledAttributeMapper.UNSET_DISABLED;
|
||||||
public static final String PATH = null;
|
public static final String PATH = null;
|
||||||
public static final FormatDateTimeFormatter DATE_TIME_FORMATTER = Joda.forPattern(DEFAULT_DATE_TIME_FORMAT);
|
|
||||||
public static final String DEFAULT_TIMESTAMP = "now";
|
public static final String DEFAULT_TIMESTAMP = "now";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,13 +91,16 @@ public class TimestampFieldMapper extends DateFieldMapper implements RootMapper
|
||||||
|
|
||||||
private EnabledAttributeMapper enabledState = EnabledAttributeMapper.UNSET_DISABLED;
|
private EnabledAttributeMapper enabledState = EnabledAttributeMapper.UNSET_DISABLED;
|
||||||
private String path = Defaults.PATH;
|
private String path = Defaults.PATH;
|
||||||
private FormatDateTimeFormatter dateTimeFormatter = Defaults.DATE_TIME_FORMATTER;
|
|
||||||
private String defaultTimestamp = Defaults.DEFAULT_TIMESTAMP;
|
private String defaultTimestamp = Defaults.DEFAULT_TIMESTAMP;
|
||||||
private boolean explicitStore = false;
|
private boolean explicitStore = false;
|
||||||
private Boolean ignoreMissing = null;
|
private Boolean ignoreMissing = null;
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
super(Defaults.NAME, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_64_BIT);
|
super(Defaults.NAME, Defaults.FIELD_TYPE, Defaults.PRECISION_STEP_64_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateFieldType fieldType() {
|
||||||
|
return (DateFieldType)fieldType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder enabled(EnabledAttributeMapper enabledState) {
|
public Builder enabled(EnabledAttributeMapper enabledState) {
|
||||||
|
@ -105,8 +114,8 @@ public class TimestampFieldMapper extends DateFieldMapper implements RootMapper
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder dateTimeFormatter(FormatDateTimeFormatter dateTimeFormatter) {
|
public Builder dateTimeFormatter(FormatDateTimeFormatter dateTimeFormatter) {
|
||||||
this.dateTimeFormatter = dateTimeFormatter;
|
fieldType().setDateTimeFormatter(dateTimeFormatter);
|
||||||
return builder;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder defaultTimestamp(String defaultTimestamp) {
|
public Builder defaultTimestamp(String defaultTimestamp) {
|
||||||
|
@ -131,9 +140,20 @@ public class TimestampFieldMapper extends DateFieldMapper implements RootMapper
|
||||||
assert fieldType.stored();
|
assert fieldType.stored();
|
||||||
fieldType.setStored(false);
|
fieldType.setStored(false);
|
||||||
}
|
}
|
||||||
return new TimestampFieldMapper(fieldType, docValues, enabledState, path, dateTimeFormatter, defaultTimestamp,
|
setupFieldType(context);
|
||||||
|
return new TimestampFieldMapper(fieldType, docValues, enabledState, path, defaultTimestamp,
|
||||||
ignoreMissing,
|
ignoreMissing,
|
||||||
ignoreMalformed(context), coerce(context), normsLoading, fieldDataSettings, context.indexSettings());
|
ignoreMalformed(context), coerce(context), fieldDataSettings, context.indexSettings());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NamedAnalyzer makeNumberAnalyzer(int precisionStep) {
|
||||||
|
return NumericDateAnalyzer.buildNamedAnalyzer(fieldType().dateTimeFormatter(), precisionStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int maxPrecisionStep() {
|
||||||
|
return 64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +210,29 @@ public class TimestampFieldMapper extends DateFieldMapper implements RootMapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FieldType defaultFieldType(Settings settings) {
|
public static class TimestampFieldType extends DateFieldType {
|
||||||
|
|
||||||
|
public TimestampFieldType() {}
|
||||||
|
|
||||||
|
protected TimestampFieldType(TimestampFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DateFieldType clone() {
|
||||||
|
return new TimestampFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override the default behavior to return a timestamp
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object valueForSearch(Object value) {
|
||||||
|
return value(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MappedFieldType defaultFieldType(Settings settings) {
|
||||||
return Version.indexCreated(settings).onOrAfter(Version.V_2_0_0) ? Defaults.FIELD_TYPE : Defaults.PRE_20_FIELD_TYPE;
|
return Version.indexCreated(settings).onOrAfter(Version.V_2_0_0) ? Defaults.FIELD_TYPE : Defaults.PRE_20_FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,23 +240,18 @@ public class TimestampFieldMapper extends DateFieldMapper implements RootMapper
|
||||||
|
|
||||||
private final String path;
|
private final String path;
|
||||||
private final String defaultTimestamp;
|
private final String defaultTimestamp;
|
||||||
private final FieldType defaultFieldType;
|
private final MappedFieldType defaultFieldType;
|
||||||
private final Boolean ignoreMissing;
|
private final Boolean ignoreMissing;
|
||||||
|
|
||||||
public TimestampFieldMapper(Settings indexSettings) {
|
public TimestampFieldMapper(Settings indexSettings) {
|
||||||
this(new FieldType(defaultFieldType(indexSettings)), null, Defaults.ENABLED, Defaults.PATH, Defaults.DATE_TIME_FORMATTER, Defaults.DEFAULT_TIMESTAMP,
|
this(defaultFieldType(indexSettings).clone(), null, Defaults.ENABLED, Defaults.PATH, Defaults.DEFAULT_TIMESTAMP,
|
||||||
null, Defaults.IGNORE_MALFORMED, Defaults.COERCE, null, null, indexSettings);
|
null, Defaults.IGNORE_MALFORMED, Defaults.COERCE, null, indexSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TimestampFieldMapper(FieldType fieldType, Boolean docValues, EnabledAttributeMapper enabledState, String path,
|
protected TimestampFieldMapper(MappedFieldType fieldType, Boolean docValues, EnabledAttributeMapper enabledState, String path,
|
||||||
FormatDateTimeFormatter dateTimeFormatter, String defaultTimestamp,
|
String defaultTimestamp, Boolean ignoreMissing, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
||||||
Boolean ignoreMissing,
|
|
||||||
Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce, Loading normsLoading,
|
|
||||||
@Nullable Settings fieldDataSettings, Settings indexSettings) {
|
@Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||||
super(new Names(Defaults.NAME, Defaults.NAME, Defaults.NAME, Defaults.NAME), dateTimeFormatter,
|
super(fieldType, docValues, Defaults.NULL_VALUE, ignoreMalformed, coerce, fieldDataSettings,
|
||||||
Defaults.PRECISION_STEP_64_BIT, Defaults.BOOST, fieldType, docValues,
|
|
||||||
Defaults.NULL_VALUE, TimeUnit.MILLISECONDS /*always milliseconds*/,
|
|
||||||
ignoreMalformed, coerce, null, normsLoading, fieldDataSettings,
|
|
||||||
indexSettings, MultiFields.empty(), null);
|
indexSettings, MultiFields.empty(), null);
|
||||||
this.enabledState = enabledState;
|
this.enabledState = enabledState;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
|
@ -224,7 +261,7 @@ public class TimestampFieldMapper extends DateFieldMapper implements RootMapper
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return defaultFieldType;
|
return defaultFieldType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,19 +286,6 @@ public class TimestampFieldMapper extends DateFieldMapper implements RootMapper
|
||||||
return this.ignoreMissing;
|
return this.ignoreMissing;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public FormatDateTimeFormatter dateTimeFormatter() {
|
|
||||||
return this.dateTimeFormatter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Override the default behavior to return a timestamp
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Object valueForSearch(Object value) {
|
|
||||||
return value(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preParse(ParseContext context) throws IOException {
|
public void preParse(ParseContext context) throws IOException {
|
||||||
super.parse(context);
|
super.parse(context);
|
||||||
|
@ -281,14 +305,14 @@ public class TimestampFieldMapper extends DateFieldMapper implements RootMapper
|
||||||
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
protected void innerParseCreateField(ParseContext context, List<Field> fields) throws IOException {
|
||||||
if (enabledState.enabled) {
|
if (enabledState.enabled) {
|
||||||
long timestamp = context.sourceToParse().timestamp();
|
long timestamp = context.sourceToParse().timestamp();
|
||||||
if (fieldType.indexOptions() == IndexOptions.NONE && !fieldType.stored() && !hasDocValues()) {
|
if (fieldType.indexOptions() == IndexOptions.NONE && !fieldType.stored() && !fieldType().hasDocValues()) {
|
||||||
context.ignoredValue(names.indexName(), String.valueOf(timestamp));
|
context.ignoredValue(fieldType.names().indexName(), String.valueOf(timestamp));
|
||||||
}
|
}
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
||||||
fields.add(new LongFieldMapper.CustomLongNumericField(this, timestamp, fieldType));
|
fields.add(new LongFieldMapper.CustomLongNumericField(this, timestamp, (NumberFieldType)fieldType));
|
||||||
}
|
}
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
fields.add(new NumericDocValuesField(names.indexName(), timestamp));
|
fields.add(new NumericDocValuesField(fieldType.names().indexName(), timestamp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,10 +330,10 @@ public class TimestampFieldMapper extends DateFieldMapper implements RootMapper
|
||||||
|
|
||||||
// if all are defaults, no sense to write it at all
|
// if all are defaults, no sense to write it at all
|
||||||
if (!includeDefaults && indexed == indexedDefault && customFieldDataSettings == null &&
|
if (!includeDefaults && indexed == indexedDefault && customFieldDataSettings == null &&
|
||||||
fieldType.stored() == Defaults.FIELD_TYPE.stored() && enabledState == Defaults.ENABLED && path == Defaults.PATH
|
fieldType.stored() == Defaults.FIELD_TYPE.stored() && enabledState == Defaults.ENABLED && path == Defaults.PATH
|
||||||
&& dateTimeFormatter.format().equals(Defaults.DATE_TIME_FORMATTER.format())
|
&& fieldType().dateTimeFormatter().format().equals(Defaults.DATE_TIME_FORMATTER.format())
|
||||||
&& Defaults.DEFAULT_TIMESTAMP.equals(defaultTimestamp)
|
&& Defaults.DEFAULT_TIMESTAMP.equals(defaultTimestamp)
|
||||||
&& defaultDocValues() == hasDocValues()) {
|
&& defaultDocValues() == fieldType().hasDocValues()) {
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
builder.startObject(CONTENT_TYPE);
|
builder.startObject(CONTENT_TYPE);
|
||||||
|
@ -326,8 +350,8 @@ public class TimestampFieldMapper extends DateFieldMapper implements RootMapper
|
||||||
if (includeDefaults || path != Defaults.PATH) {
|
if (includeDefaults || path != Defaults.PATH) {
|
||||||
builder.field("path", path);
|
builder.field("path", path);
|
||||||
}
|
}
|
||||||
if (includeDefaults || !dateTimeFormatter.format().equals(Defaults.DATE_TIME_FORMATTER.format())) {
|
if (includeDefaults || !fieldType().dateTimeFormatter().format().equals(Defaults.DATE_TIME_FORMATTER.format())) {
|
||||||
builder.field("format", dateTimeFormatter.format());
|
builder.field("format", fieldType().dateTimeFormatter().format());
|
||||||
}
|
}
|
||||||
if (includeDefaults || !Defaults.DEFAULT_TIMESTAMP.equals(defaultTimestamp)) {
|
if (includeDefaults || !Defaults.DEFAULT_TIMESTAMP.equals(defaultTimestamp)) {
|
||||||
builder.field("default", defaultTimestamp);
|
builder.field("default", defaultTimestamp);
|
||||||
|
@ -338,7 +362,7 @@ public class TimestampFieldMapper extends DateFieldMapper implements RootMapper
|
||||||
if (customFieldDataSettings != null) {
|
if (customFieldDataSettings != null) {
|
||||||
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
||||||
} else if (includeDefaults) {
|
} else if (includeDefaults) {
|
||||||
builder.field("fielddata", (Map) fieldDataType.getSettings().getAsMap());
|
builder.field("fielddata", (Map) fieldType.fieldDataType().getSettings().getAsMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
package org.elasticsearch.index.mapper.internal;
|
package org.elasticsearch.index.mapper.internal;
|
||||||
|
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.document.SortedSetDocValuesField;
|
import org.apache.lucene.document.SortedSetDocValuesField;
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
|
@ -36,6 +35,7 @@ import org.elasticsearch.common.lucene.Lucene;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -65,13 +65,16 @@ public class TypeFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
public static class Defaults extends AbstractFieldMapper.Defaults {
|
public static class Defaults extends AbstractFieldMapper.Defaults {
|
||||||
public static final String NAME = TypeFieldMapper.NAME;
|
public static final String NAME = TypeFieldMapper.NAME;
|
||||||
|
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new TypeFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
||||||
FIELD_TYPE.setTokenized(false);
|
FIELD_TYPE.setTokenized(false);
|
||||||
FIELD_TYPE.setStored(false);
|
FIELD_TYPE.setStored(false);
|
||||||
FIELD_TYPE.setOmitNorms(true);
|
FIELD_TYPE.setOmitNorms(true);
|
||||||
|
FIELD_TYPE.setIndexAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setNames(new MappedFieldType.Names(NAME));
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,13 +82,14 @@ public class TypeFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
public static class Builder extends AbstractFieldMapper.Builder<Builder, TypeFieldMapper> {
|
public static class Builder extends AbstractFieldMapper.Builder<Builder, TypeFieldMapper> {
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
super(Defaults.NAME, new FieldType(Defaults.FIELD_TYPE));
|
super(Defaults.NAME, Defaults.FIELD_TYPE);
|
||||||
indexName = Defaults.NAME;
|
indexName = Defaults.NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeFieldMapper build(BuilderContext context) {
|
public TypeFieldMapper build(BuilderContext context) {
|
||||||
return new TypeFieldMapper(name, indexName, boost, fieldType, fieldDataSettings, context.indexSettings());
|
fieldType.setNames(new MappedFieldType.Names(name, indexName, indexName, name));
|
||||||
|
return new TypeFieldMapper(fieldType, fieldDataSettings, context.indexSettings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,17 +105,53 @@ public class TypeFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeFieldMapper(Settings indexSettings) {
|
public static class TypeFieldType extends MappedFieldType {
|
||||||
this(Defaults.NAME, Defaults.NAME, Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), null, indexSettings);
|
|
||||||
|
public TypeFieldType() {
|
||||||
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TypeFieldType(TypeFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new TypeFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useTermQueryWithQueryString() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query termQuery(Object value, @Nullable QueryParseContext context) {
|
||||||
|
if (indexOptions() == IndexOptions.NONE) {
|
||||||
|
return new ConstantScoreQuery(new PrefixQuery(new Term(UidFieldMapper.NAME, Uid.typePrefixAsBytes(BytesRefs.toBytesRef(value)))));
|
||||||
|
}
|
||||||
|
return new ConstantScoreQuery(new TermQuery(createTerm(value)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeFieldMapper(String name, String indexName, float boost, FieldType fieldType, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
public TypeFieldMapper(Settings indexSettings) {
|
||||||
super(new Names(name, indexName, indexName, name), boost, fieldType, false, Lucene.KEYWORD_ANALYZER,
|
this(Defaults.FIELD_TYPE.clone(), null, indexSettings);
|
||||||
Lucene.KEYWORD_ANALYZER, null, null, fieldDataSettings, indexSettings);
|
}
|
||||||
|
|
||||||
|
public TypeFieldMapper(MappedFieldType fieldType, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||||
|
super(fieldType, false, fieldDataSettings, indexSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,26 +160,6 @@ public class TypeFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
return new FieldDataType("string");
|
return new FieldDataType("string");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query termQuery(Object value, @Nullable QueryParseContext context) {
|
|
||||||
if (fieldType.indexOptions() == IndexOptions.NONE) {
|
|
||||||
return new ConstantScoreQuery(new PrefixQuery(new Term(UidFieldMapper.NAME, Uid.typePrefixAsBytes(BytesRefs.toBytesRef(value)))));
|
|
||||||
}
|
|
||||||
return new ConstantScoreQuery(new TermQuery(createTerm(value)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean useTermQueryWithQueryString() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preParse(ParseContext context) throws IOException {
|
public void preParse(ParseContext context) throws IOException {
|
||||||
|
@ -161,9 +181,9 @@ public class TypeFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
if (fieldType.indexOptions() == IndexOptions.NONE && !fieldType.stored()) {
|
if (fieldType.indexOptions() == IndexOptions.NONE && !fieldType.stored()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fields.add(new Field(names.indexName(), context.type(), fieldType));
|
fields.add(new Field(fieldType.names().indexName(), context.type(), fieldType));
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
fields.add(new SortedSetDocValuesField(names.indexName(), new BytesRef(context.type())));
|
fields.add(new SortedSetDocValuesField(fieldType.names().indexName(), new BytesRef(context.type())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ package org.elasticsearch.index.mapper.internal;
|
||||||
|
|
||||||
import org.apache.lucene.document.BinaryDocValuesField;
|
import org.apache.lucene.document.BinaryDocValuesField;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.index.IndexableField;
|
import org.apache.lucene.index.IndexableField;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
|
@ -32,6 +31,7 @@ import org.elasticsearch.common.lucene.Lucene;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -61,17 +61,20 @@ public class UidFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
public static class Defaults extends AbstractFieldMapper.Defaults {
|
public static class Defaults extends AbstractFieldMapper.Defaults {
|
||||||
public static final String NAME = UidFieldMapper.NAME;
|
public static final String NAME = UidFieldMapper.NAME;
|
||||||
|
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new UidFieldType();
|
||||||
public static final FieldType NESTED_FIELD_TYPE;
|
public static final MappedFieldType NESTED_FIELD_TYPE;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
|
||||||
FIELD_TYPE.setTokenized(false);
|
FIELD_TYPE.setTokenized(false);
|
||||||
FIELD_TYPE.setStored(true);
|
FIELD_TYPE.setStored(true);
|
||||||
FIELD_TYPE.setOmitNorms(true);
|
FIELD_TYPE.setOmitNorms(true);
|
||||||
|
FIELD_TYPE.setIndexAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER);
|
||||||
|
FIELD_TYPE.setNames(new MappedFieldType.Names(NAME));
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
|
|
||||||
NESTED_FIELD_TYPE = new FieldType(FIELD_TYPE);
|
NESTED_FIELD_TYPE = FIELD_TYPE.clone();
|
||||||
NESTED_FIELD_TYPE.setStored(false);
|
NESTED_FIELD_TYPE.setStored(false);
|
||||||
NESTED_FIELD_TYPE.freeze();
|
NESTED_FIELD_TYPE.freeze();
|
||||||
}
|
}
|
||||||
|
@ -86,7 +89,8 @@ public class UidFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UidFieldMapper build(BuilderContext context) {
|
public UidFieldMapper build(BuilderContext context) {
|
||||||
return new UidFieldMapper(name, indexName, docValues, fieldDataSettings, context.indexSettings());
|
fieldType.setNames(new MappedFieldType.Names(name, indexName, indexName, name));
|
||||||
|
return new UidFieldMapper(fieldType, docValues, fieldDataSettings, context.indexSettings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,13 +106,36 @@ public class UidFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public UidFieldMapper(Settings indexSettings) {
|
public static class UidFieldType extends MappedFieldType {
|
||||||
this(Defaults.NAME, Defaults.NAME, null, null, indexSettings);
|
|
||||||
|
public UidFieldType() {
|
||||||
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected UidFieldType(UidFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new UidFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Uid value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Uid.createUid(value.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected UidFieldMapper(String name, String indexName, Boolean docValues, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
public UidFieldMapper(Settings indexSettings) {
|
||||||
super(new Names(name, indexName, indexName, name), Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), docValuesEnabled(docValues, indexSettings),
|
this(Defaults.FIELD_TYPE.clone(), null, null, indexSettings);
|
||||||
Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER, null, null, fieldDataSettings, indexSettings);
|
}
|
||||||
|
|
||||||
|
protected UidFieldMapper(MappedFieldType fieldType, Boolean docValues, @Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||||
|
super(fieldType, docValuesEnabled(docValues, indexSettings), fieldDataSettings, indexSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Boolean docValuesEnabled(Boolean docValues, Settings indexSettings) {
|
static Boolean docValuesEnabled(Boolean docValues, Settings indexSettings) {
|
||||||
|
@ -119,7 +146,7 @@ public class UidFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,21 +198,13 @@ public class UidFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
Field uid = new Field(NAME, Uid.createUid(context.stringBuilder(), context.type(), context.id()), Defaults.FIELD_TYPE);
|
Field uid = new Field(NAME, Uid.createUid(context.stringBuilder(), context.type(), context.id()), Defaults.FIELD_TYPE);
|
||||||
context.uid(uid);
|
context.uid(uid);
|
||||||
fields.add(uid);
|
fields.add(uid);
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
fields.add(new BinaryDocValuesField(NAME, new BytesRef(uid.stringValue())));
|
fields.add(new BinaryDocValuesField(NAME, new BytesRef(uid.stringValue())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Uid value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return Uid.createUid(value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Term term(String uid) {
|
public Term term(String uid) {
|
||||||
return createTerm(uid);
|
return new Term(fieldType().names().indexName(), fieldType().indexedValueForSearch(uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -210,7 +229,7 @@ public class UidFieldMapper extends AbstractFieldMapper implements RootMapper {
|
||||||
if (customFieldDataSettings != null) {
|
if (customFieldDataSettings != null) {
|
||||||
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
builder.field("fielddata", (Map) customFieldDataSettings.getAsMap());
|
||||||
} else if (includeDefaults) {
|
} else if (includeDefaults) {
|
||||||
builder.field("fielddata", (Map) fieldDataType.getSettings().getAsMap());
|
builder.field("fielddata", (Map) fieldType.fieldDataType().getSettings().getAsMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
|
|
|
@ -20,13 +20,14 @@
|
||||||
package org.elasticsearch.index.mapper.internal;
|
package org.elasticsearch.index.mapper.internal;
|
||||||
|
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.document.NumericDocValuesField;
|
import org.apache.lucene.document.NumericDocValuesField;
|
||||||
|
import org.apache.lucene.index.DocValuesType;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -52,9 +53,13 @@ public class VersionFieldMapper extends AbstractFieldMapper implements RootMappe
|
||||||
public static class Defaults {
|
public static class Defaults {
|
||||||
|
|
||||||
public static final String NAME = VersionFieldMapper.NAME;
|
public static final String NAME = VersionFieldMapper.NAME;
|
||||||
public static final float BOOST = 1.0f;
|
public static final MappedFieldType FIELD_TYPE = new VersionFieldType();
|
||||||
public static final FieldType FIELD_TYPE = NumericDocValuesField.TYPE;
|
|
||||||
|
|
||||||
|
static {
|
||||||
|
FIELD_TYPE.setNames(new MappedFieldType.Names(NAME));
|
||||||
|
FIELD_TYPE.setDocValuesType(DocValuesType.NUMERIC);
|
||||||
|
FIELD_TYPE.freeze();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder extends Mapper.Builder<Builder, VersionFieldMapper> {
|
public static class Builder extends Mapper.Builder<Builder, VersionFieldMapper> {
|
||||||
|
@ -86,6 +91,31 @@ public class VersionFieldMapper extends AbstractFieldMapper implements RootMappe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class VersionFieldType extends MappedFieldType {
|
||||||
|
|
||||||
|
public VersionFieldType() {
|
||||||
|
super(AbstractFieldMapper.Defaults.FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected VersionFieldType(VersionFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappedFieldType clone() {
|
||||||
|
return new VersionFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long value(Object value) {
|
||||||
|
if (value == null || (value instanceof Long)) {
|
||||||
|
return (Long) value;
|
||||||
|
} else {
|
||||||
|
return Long.parseLong(value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final ThreadLocal<Field> fieldCache = new ThreadLocal<Field>() {
|
private final ThreadLocal<Field> fieldCache = new ThreadLocal<Field>() {
|
||||||
@Override
|
@Override
|
||||||
protected Field initialValue() {
|
protected Field initialValue() {
|
||||||
|
@ -94,7 +124,7 @@ public class VersionFieldMapper extends AbstractFieldMapper implements RootMappe
|
||||||
};
|
};
|
||||||
|
|
||||||
public VersionFieldMapper(Settings indexSettings) {
|
public VersionFieldMapper(Settings indexSettings) {
|
||||||
super(new Names(NAME, NAME, NAME, NAME), Defaults.BOOST, Defaults.FIELD_TYPE, true, null, null, null, null, null, indexSettings);
|
super(Defaults.FIELD_TYPE, true, null, indexSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -116,15 +146,6 @@ public class VersionFieldMapper extends AbstractFieldMapper implements RootMappe
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long value(Object value) {
|
|
||||||
if (value == null || (value instanceof Long)) {
|
|
||||||
return (Long) value;
|
|
||||||
} else {
|
|
||||||
return Long.parseLong(value.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postParse(ParseContext context) throws IOException {
|
public void postParse(ParseContext context) throws IOException {
|
||||||
// In the case of nested docs, let's fill nested docs with version=1 so that Lucene doesn't write a Bitset for documents
|
// In the case of nested docs, let's fill nested docs with version=1 so that Lucene doesn't write a Bitset for documents
|
||||||
|
@ -136,7 +157,7 @@ public class VersionFieldMapper extends AbstractFieldMapper implements RootMappe
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,8 @@
|
||||||
package org.elasticsearch.index.mapper.ip;
|
package org.elasticsearch.index.mapper.ip;
|
||||||
|
|
||||||
import com.google.common.net.InetAddresses;
|
import com.google.common.net.InetAddresses;
|
||||||
|
|
||||||
import org.apache.lucene.analysis.NumericTokenStream;
|
import org.apache.lucene.analysis.NumericTokenStream;
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.FieldType;
|
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
import org.apache.lucene.search.ConstantScoreQuery;
|
import org.apache.lucene.search.ConstantScoreQuery;
|
||||||
import org.apache.lucene.search.NumericRangeQuery;
|
import org.apache.lucene.search.NumericRangeQuery;
|
||||||
|
@ -43,6 +41,7 @@ import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||||
import org.elasticsearch.index.analysis.NumericAnalyzer;
|
import org.elasticsearch.index.analysis.NumericAnalyzer;
|
||||||
import org.elasticsearch.index.analysis.NumericTokenizer;
|
import org.elasticsearch.index.analysis.NumericTokenizer;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.Mapper;
|
import org.elasticsearch.index.mapper.Mapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||||
|
@ -51,7 +50,6 @@ import org.elasticsearch.index.mapper.ParseContext;
|
||||||
import org.elasticsearch.index.mapper.core.LongFieldMapper.CustomLongNumericField;
|
import org.elasticsearch.index.mapper.core.LongFieldMapper.CustomLongNumericField;
|
||||||
import org.elasticsearch.index.mapper.core.NumberFieldMapper;
|
import org.elasticsearch.index.mapper.core.NumberFieldMapper;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -101,7 +99,7 @@ public class IpFieldMapper extends NumberFieldMapper {
|
||||||
public static class Defaults extends NumberFieldMapper.Defaults {
|
public static class Defaults extends NumberFieldMapper.Defaults {
|
||||||
public static final String NULL_VALUE = null;
|
public static final String NULL_VALUE = null;
|
||||||
|
|
||||||
public static final FieldType FIELD_TYPE = new FieldType(NumberFieldMapper.Defaults.FIELD_TYPE);
|
public static final MappedFieldType FIELD_TYPE = new IpFieldType();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
FIELD_TYPE.freeze();
|
FIELD_TYPE.freeze();
|
||||||
|
@ -113,7 +111,7 @@ public class IpFieldMapper extends NumberFieldMapper {
|
||||||
protected String nullValue = Defaults.NULL_VALUE;
|
protected String nullValue = Defaults.NULL_VALUE;
|
||||||
|
|
||||||
public Builder(String name) {
|
public Builder(String name) {
|
||||||
super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_64_BIT);
|
super(name, Defaults.FIELD_TYPE, Defaults.PRECISION_STEP_64_BIT);
|
||||||
builder = this;
|
builder = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,13 +122,23 @@ public class IpFieldMapper extends NumberFieldMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IpFieldMapper build(BuilderContext context) {
|
public IpFieldMapper build(BuilderContext context) {
|
||||||
fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
|
setupFieldType(context);
|
||||||
IpFieldMapper fieldMapper = new IpFieldMapper(buildNames(context),
|
IpFieldMapper fieldMapper = new IpFieldMapper(fieldType, docValues, nullValue, ignoreMalformed(context), coerce(context),
|
||||||
fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue, ignoreMalformed(context), coerce(context),
|
fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
||||||
similarity, normsLoading, fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
|
|
||||||
fieldMapper.includeInAll(includeInAll);
|
fieldMapper.includeInAll(includeInAll);
|
||||||
return fieldMapper;
|
return fieldMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NamedAnalyzer makeNumberAnalyzer(int precisionStep) {
|
||||||
|
String name = precisionStep == Integer.MAX_VALUE ? "_ip/max" : ("_ip/" + precisionStep);
|
||||||
|
return new NamedAnalyzer(name, new NumericIpAnalyzer(precisionStep));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int maxPrecisionStep() {
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TypeParser implements Mapper.TypeParser {
|
public static class TypeParser implements Mapper.TypeParser {
|
||||||
|
@ -154,21 +162,90 @@ public class IpFieldMapper extends NumberFieldMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class IpFieldType extends NumberFieldType {
|
||||||
|
|
||||||
|
public IpFieldType() {}
|
||||||
|
|
||||||
|
protected IpFieldType(IpFieldType ref) {
|
||||||
|
super(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NumberFieldType clone() {
|
||||||
|
return new IpFieldType(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long value(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).longValue();
|
||||||
|
}
|
||||||
|
if (value instanceof BytesRef) {
|
||||||
|
return Numbers.bytesToLong((BytesRef) value);
|
||||||
|
}
|
||||||
|
return ipToLong(value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IPs should return as a string.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object valueForSearch(Object value) {
|
||||||
|
Long val = value(value);
|
||||||
|
if (val == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return longToIp(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BytesRef indexedValueForSearch(Object value) {
|
||||||
|
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
||||||
|
NumericUtils.longToPrefixCoded(parseValue(value), 0, bytesRef); // 0 because of exact match
|
||||||
|
return bytesRef.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
||||||
|
return NumericRangeQuery.newLongRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
lowerTerm == null ? null : parseValue(lowerTerm),
|
||||||
|
upperTerm == null ? null : parseValue(upperTerm),
|
||||||
|
includeLower, includeUpper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
||||||
|
long iValue = ipToLong(value);
|
||||||
|
long iSim;
|
||||||
|
try {
|
||||||
|
iSim = ipToLong(fuzziness.asString());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
iSim = fuzziness.asLong();
|
||||||
|
}
|
||||||
|
return NumericRangeQuery.newLongRange(names().indexName(), numericPrecisionStep(),
|
||||||
|
iValue - iSim,
|
||||||
|
iValue + iSim,
|
||||||
|
true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String nullValue;
|
private String nullValue;
|
||||||
|
|
||||||
protected IpFieldMapper(Names names, int precisionStep, float boost, FieldType fieldType, Boolean docValues,
|
protected IpFieldMapper(MappedFieldType fieldType, Boolean docValues,
|
||||||
String nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
String nullValue, Explicit<Boolean> ignoreMalformed, Explicit<Boolean> coerce,
|
||||||
SimilarityProvider similarity, Loading normsLoading, @Nullable Settings fieldDataSettings,
|
@Nullable Settings fieldDataSettings,
|
||||||
Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
|
||||||
super(names, precisionStep, boost, fieldType, docValues,
|
super(fieldType, docValues, ignoreMalformed, coerce,
|
||||||
ignoreMalformed, coerce, new NamedAnalyzer("_ip/" + precisionStep, new NumericIpAnalyzer(precisionStep)),
|
fieldDataSettings, indexSettings, multiFields, copyTo);
|
||||||
new NamedAnalyzer("_ip/max", new NumericIpAnalyzer(Integer.MAX_VALUE)),
|
|
||||||
similarity, normsLoading, fieldDataSettings, indexSettings, multiFields, copyTo);
|
|
||||||
this.nullValue = nullValue;
|
this.nullValue = nullValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldType defaultFieldType() {
|
public MappedFieldType defaultFieldType() {
|
||||||
return Defaults.FIELD_TYPE;
|
return Defaults.FIELD_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,45 +254,7 @@ public class IpFieldMapper extends NumberFieldMapper {
|
||||||
return new FieldDataType("long");
|
return new FieldDataType("long");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private static long parseValue(Object value) {
|
||||||
protected int maxPrecisionStep() {
|
|
||||||
return 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long value(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (value instanceof Number) {
|
|
||||||
return ((Number) value).longValue();
|
|
||||||
}
|
|
||||||
if (value instanceof BytesRef) {
|
|
||||||
return Numbers.bytesToLong((BytesRef) value);
|
|
||||||
}
|
|
||||||
return ipToLong(value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IPs should return as a string.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Object valueForSearch(Object value) {
|
|
||||||
Long val = value(value);
|
|
||||||
if (val == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return longToIp(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BytesRef indexedValueForSearch(Object value) {
|
|
||||||
BytesRefBuilder bytesRef = new BytesRefBuilder();
|
|
||||||
NumericUtils.longToPrefixCoded(parseValue(value), 0, bytesRef); // 0 because of exact match
|
|
||||||
return bytesRef.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private long parseValue(Object value) {
|
|
||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
return ((Number) value).longValue();
|
return ((Number) value).longValue();
|
||||||
}
|
}
|
||||||
|
@ -225,29 +264,6 @@ public class IpFieldMapper extends NumberFieldMapper {
|
||||||
return ipToLong(value.toString());
|
return ipToLong(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Query fuzzyQuery(String value, Fuzziness fuzziness, int prefixLength, int maxExpansions, boolean transpositions) {
|
|
||||||
long iValue = ipToLong(value);
|
|
||||||
long iSim;
|
|
||||||
try {
|
|
||||||
iSim = ipToLong(fuzziness.asString());
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
iSim = fuzziness.asLong();
|
|
||||||
}
|
|
||||||
return NumericRangeQuery.newLongRange(names.indexName(), precisionStep,
|
|
||||||
iValue - iSim,
|
|
||||||
iValue + iSim,
|
|
||||||
true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
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
|
@Override
|
||||||
public Query nullValueFilter() {
|
public Query nullValueFilter() {
|
||||||
if (nullValue == null) {
|
if (nullValue == null) {
|
||||||
|
@ -276,16 +292,16 @@ public class IpFieldMapper extends NumberFieldMapper {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (context.includeInAll(includeInAll, this)) {
|
if (context.includeInAll(includeInAll, this)) {
|
||||||
context.allEntries().addText(names.fullName(), ipAsString, boost);
|
context.allEntries().addText(fieldType.names().fullName(), ipAsString, fieldType.boost());
|
||||||
}
|
}
|
||||||
|
|
||||||
final long value = ipToLong(ipAsString);
|
final long value = ipToLong(ipAsString);
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
||||||
CustomLongNumericField field = new CustomLongNumericField(this, value, fieldType);
|
CustomLongNumericField field = new CustomLongNumericField(this, value, fieldType);
|
||||||
field.setBoost(boost);
|
field.setBoost(fieldType.boost());
|
||||||
fields.add(field);
|
fields.add(field);
|
||||||
}
|
}
|
||||||
if (hasDocValues()) {
|
if (fieldType().hasDocValues()) {
|
||||||
addDocValue(context, fields, value);
|
addDocValue(context, fields, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,8 +326,8 @@ public class IpFieldMapper extends NumberFieldMapper {
|
||||||
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
|
||||||
super.doXContentBody(builder, includeDefaults, params);
|
super.doXContentBody(builder, includeDefaults, params);
|
||||||
|
|
||||||
if (includeDefaults || precisionStep != Defaults.PRECISION_STEP_64_BIT) {
|
if (includeDefaults || fieldType.numericPrecisionStep() != Defaults.PRECISION_STEP_64_BIT) {
|
||||||
builder.field("precision_step", precisionStep);
|
builder.field("precision_step", fieldType.numericPrecisionStep());
|
||||||
}
|
}
|
||||||
if (includeDefaults || nullValue != null) {
|
if (includeDefaults || nullValue != null) {
|
||||||
builder.field("null_value", nullValue);
|
builder.field("null_value", nullValue);
|
||||||
|
|
|
@ -165,7 +165,7 @@ public class CommonTermsQueryParser implements QueryParser {
|
||||||
String field;
|
String field;
|
||||||
FieldMapper mapper = parseContext.fieldMapper(fieldName);
|
FieldMapper mapper = parseContext.fieldMapper(fieldName);
|
||||||
if (mapper != null) {
|
if (mapper != null) {
|
||||||
field = mapper.names().indexName();
|
field = mapper.fieldType().names().indexName();
|
||||||
} else {
|
} else {
|
||||||
field = fieldName;
|
field = fieldName;
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ public class CommonTermsQueryParser implements QueryParser {
|
||||||
Analyzer analyzer = null;
|
Analyzer analyzer = null;
|
||||||
if (queryAnalyzer == null) {
|
if (queryAnalyzer == null) {
|
||||||
if (mapper != null) {
|
if (mapper != null) {
|
||||||
analyzer = mapper.searchAnalyzer();
|
analyzer = mapper.fieldType().searchAnalyzer();
|
||||||
}
|
}
|
||||||
if (analyzer == null && mapper != null) {
|
if (analyzer == null && mapper != null) {
|
||||||
analyzer = parseContext.getSearchAnalyzer(mapper);
|
analyzer = parseContext.getSearchAnalyzer(mapper);
|
||||||
|
|
|
@ -98,7 +98,7 @@ public class ExistsQueryParser implements QueryParser {
|
||||||
if (fieldNamesMapper!= null && fieldNamesMapper.enabled()) {
|
if (fieldNamesMapper!= null && fieldNamesMapper.enabled()) {
|
||||||
final String f;
|
final String f;
|
||||||
if (mapper != null) {
|
if (mapper != null) {
|
||||||
f = mapper.names().indexName();
|
f = mapper.fieldType().names().indexName();
|
||||||
} else {
|
} else {
|
||||||
f = field;
|
f = field;
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ public class FieldMaskingSpanQueryParser implements QueryParser {
|
||||||
|
|
||||||
FieldMapper mapper = parseContext.fieldMapper(field);
|
FieldMapper mapper = parseContext.fieldMapper(field);
|
||||||
if (mapper != null) {
|
if (mapper != null) {
|
||||||
field = mapper.names().indexName();
|
field = mapper.fieldType().names().indexName();
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldMaskingSpanQuery query = new FieldMaskingSpanQuery(inner, field);
|
FieldMaskingSpanQuery query = new FieldMaskingSpanQuery(inner, field);
|
||||||
|
|
|
@ -150,9 +150,9 @@ public class GeoShapeQueryParser implements QueryParser {
|
||||||
|
|
||||||
GeoShapeFieldMapper shapeFieldMapper = (GeoShapeFieldMapper) fieldMapper;
|
GeoShapeFieldMapper shapeFieldMapper = (GeoShapeFieldMapper) fieldMapper;
|
||||||
|
|
||||||
PrefixTreeStrategy strategy = shapeFieldMapper.defaultStrategy();
|
PrefixTreeStrategy strategy = shapeFieldMapper.fieldType().defaultStrategy();
|
||||||
if (strategyName != null) {
|
if (strategyName != null) {
|
||||||
strategy = shapeFieldMapper.resolveStrategy(strategyName);
|
strategy = shapeFieldMapper.fieldType().resolveStrategy(strategyName);
|
||||||
}
|
}
|
||||||
Query query;
|
Query query;
|
||||||
if (strategy instanceof RecursivePrefixTreeStrategy && shapeRelation == ShapeRelation.DISJOINT) {
|
if (strategy instanceof RecursivePrefixTreeStrategy && shapeRelation == ShapeRelation.DISJOINT) {
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser.Token;
|
import org.elasticsearch.common.xcontent.XContentParser.Token;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.core.StringFieldMapper;
|
import org.elasticsearch.index.mapper.core.StringFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
||||||
|
|
||||||
|
@ -71,11 +72,11 @@ public class GeohashCellQuery {
|
||||||
* @return a new GeoBoundinboxfilter
|
* @return a new GeoBoundinboxfilter
|
||||||
*/
|
*/
|
||||||
public static Query create(QueryParseContext context, GeoPointFieldMapper fieldMapper, String geohash, @Nullable List<CharSequence> geohashes) {
|
public static Query create(QueryParseContext context, GeoPointFieldMapper fieldMapper, String geohash, @Nullable List<CharSequence> geohashes) {
|
||||||
if (fieldMapper.geoHashStringMapper() == null) {
|
MappedFieldType geoHashMapper = fieldMapper.fieldType().geohashFieldType();
|
||||||
|
if (geoHashMapper == null) {
|
||||||
throw new IllegalArgumentException("geohash filter needs geohash_prefix to be enabled");
|
throw new IllegalArgumentException("geohash filter needs geohash_prefix to be enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
StringFieldMapper geoHashMapper = fieldMapper.geoHashStringMapper();
|
|
||||||
if (geohashes == null || geohashes.size() == 0) {
|
if (geohashes == null || geohashes.size() == 0) {
|
||||||
return geoHashMapper.termQuery(geohash, context);
|
return geoHashMapper.termQuery(geohash, context);
|
||||||
} else {
|
} else {
|
||||||
|
@ -246,7 +247,7 @@ public class GeohashCellQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
GeoPointFieldMapper geoMapper = ((GeoPointFieldMapper) mapper);
|
GeoPointFieldMapper geoMapper = ((GeoPointFieldMapper) mapper);
|
||||||
if (!geoMapper.isEnableGeohashPrefix()) {
|
if (!geoMapper.fieldType().isGeohashPrefixEnabled()) {
|
||||||
throw new QueryParsingException(parseContext, "can't execute geohash_cell on field [" + fieldName
|
throw new QueryParsingException(parseContext, "can't execute geohash_cell on field [" + fieldName
|
||||||
+ "], geohash_prefix is not enabled");
|
+ "], geohash_prefix is not enabled");
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ public class MissingQueryParser implements QueryParser {
|
||||||
if (fieldNamesMapper != null && fieldNamesMapper.enabled()) {
|
if (fieldNamesMapper != null && fieldNamesMapper.enabled()) {
|
||||||
final String f;
|
final String f;
|
||||||
if (mapper != null) {
|
if (mapper != null) {
|
||||||
f = mapper.names().indexName();
|
f = mapper.fieldType().names().indexName();
|
||||||
} else {
|
} else {
|
||||||
f = field;
|
f = field;
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,7 +167,7 @@ public class MoreLikeThisQueryParser implements QueryParser {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||||
String field = parser.text();
|
String field = parser.text();
|
||||||
FieldMapper mapper = parseContext.fieldMapper(field);
|
FieldMapper mapper = parseContext.fieldMapper(field);
|
||||||
moreLikeFields.add(mapper == null ? field : mapper.names().indexName());
|
moreLikeFields.add(mapper == null ? field : mapper.fieldType().names().indexName());
|
||||||
}
|
}
|
||||||
} else if (Fields.DOCUMENT_IDS.match(currentFieldName, parseContext.parseFlags())) {
|
} else if (Fields.DOCUMENT_IDS.match(currentFieldName, parseContext.parseFlags())) {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||||
|
|
|
@ -287,8 +287,8 @@ public class QueryParseContext {
|
||||||
* TODO: remove this by moving defaults into mappers themselves
|
* TODO: remove this by moving defaults into mappers themselves
|
||||||
*/
|
*/
|
||||||
public Analyzer getSearchAnalyzer(FieldMapper mapper) {
|
public Analyzer getSearchAnalyzer(FieldMapper mapper) {
|
||||||
if (mapper.searchAnalyzer() != null) {
|
if (mapper.fieldType().searchAnalyzer() != null) {
|
||||||
return mapper.searchAnalyzer();
|
return mapper.fieldType().searchAnalyzer();
|
||||||
}
|
}
|
||||||
return mapperService().searchAnalyzer();
|
return mapperService().searchAnalyzer();
|
||||||
}
|
}
|
||||||
|
@ -297,8 +297,8 @@ public class QueryParseContext {
|
||||||
* TODO: remove this by moving defaults into mappers themselves
|
* TODO: remove this by moving defaults into mappers themselves
|
||||||
*/
|
*/
|
||||||
public Analyzer getSearchQuoteAnalyzer(FieldMapper mapper) {
|
public Analyzer getSearchQuoteAnalyzer(FieldMapper mapper) {
|
||||||
if (mapper.searchQuoteAnalyzer() != null) {
|
if (mapper.fieldType().searchQuoteAnalyzer() != null) {
|
||||||
return mapper.searchQuoteAnalyzer();
|
return mapper.fieldType().searchQuoteAnalyzer();
|
||||||
}
|
}
|
||||||
return mapperService().searchQuoteAnalyzer();
|
return mapperService().searchQuoteAnalyzer();
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,7 @@ public class RangeQueryParser implements QueryParser {
|
||||||
"[range] time_zone when using ms since epoch format as it's UTC based can not be applied to [" + fieldName
|
"[range] time_zone when using ms since epoch format as it's UTC based can not be applied to [" + fieldName
|
||||||
+ "]");
|
+ "]");
|
||||||
}
|
}
|
||||||
query = ((DateFieldMapper) mapper).rangeQuery(from, to, includeLower, includeUpper, timeZone, forcedDateParser, parseContext);
|
query = ((DateFieldMapper) mapper).fieldType().rangeQuery(from, to, includeLower, includeUpper, timeZone, forcedDateParser, parseContext);
|
||||||
} else {
|
} else {
|
||||||
if (timeZone != null) {
|
if (timeZone != null) {
|
||||||
throw new QueryParsingException(parseContext, "[range] time_zone can not be applied to non date field ["
|
throw new QueryParsingException(parseContext, "[range] time_zone can not be applied to non date field ["
|
||||||
|
|
|
@ -132,7 +132,7 @@ public class SimpleQueryStringParser implements QueryParser {
|
||||||
} else {
|
} else {
|
||||||
FieldMapper mapper = parseContext.fieldMapper(fField);
|
FieldMapper mapper = parseContext.fieldMapper(fField);
|
||||||
if (mapper != null) {
|
if (mapper != null) {
|
||||||
fieldsAndWeights.put(mapper.names().indexName(), fBoost);
|
fieldsAndWeights.put(mapper.fieldType().names().indexName(), fBoost);
|
||||||
} else {
|
} else {
|
||||||
fieldsAndWeights.put(fField, fBoost);
|
fieldsAndWeights.put(fField, fBoost);
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ public class SpanTermQueryParser implements QueryParser {
|
||||||
BytesRef valueBytes = null;
|
BytesRef valueBytes = null;
|
||||||
FieldMapper mapper = parseContext.fieldMapper(fieldName);
|
FieldMapper mapper = parseContext.fieldMapper(fieldName);
|
||||||
if (mapper != null) {
|
if (mapper != null) {
|
||||||
fieldName = mapper.names().indexName();
|
fieldName = mapper.fieldType().names().indexName();
|
||||||
valueBytes = mapper.indexedValueForSearch(value);
|
valueBytes = mapper.indexedValueForSearch(value);
|
||||||
}
|
}
|
||||||
if (valueBytes == null) {
|
if (valueBytes == null) {
|
||||||
|
|
|
@ -160,7 +160,7 @@ public class TermsQueryParser implements QueryParser {
|
||||||
|
|
||||||
FieldMapper fieldMapper = parseContext.fieldMapper(fieldName);
|
FieldMapper fieldMapper = parseContext.fieldMapper(fieldName);
|
||||||
if (fieldMapper != null) {
|
if (fieldMapper != null) {
|
||||||
fieldName = fieldMapper.names().indexName();
|
fieldName = fieldMapper.fieldType().names().indexName();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lookupId != null) {
|
if (lookupId != null) {
|
||||||
|
|
|
@ -95,7 +95,7 @@ public class WildcardQueryParser implements QueryParser {
|
||||||
BytesRef valueBytes;
|
BytesRef valueBytes;
|
||||||
FieldMapper mapper = parseContext.fieldMapper(fieldName);
|
FieldMapper mapper = parseContext.fieldMapper(fieldName);
|
||||||
if (mapper != null) {
|
if (mapper != null) {
|
||||||
fieldName = mapper.names().indexName();
|
fieldName = mapper.fieldType().names().indexName();
|
||||||
valueBytes = mapper.indexedValueForSearch(value);
|
valueBytes = mapper.indexedValueForSearch(value);
|
||||||
} else {
|
} else {
|
||||||
valueBytes = new BytesRef(value);
|
valueBytes = new BytesRef(value);
|
||||||
|
|
|
@ -263,7 +263,7 @@ public abstract class DecayFunctionParser implements ScoreFunctionParser {
|
||||||
}
|
}
|
||||||
long origin = SearchContext.current().nowInMillis();
|
long origin = SearchContext.current().nowInMillis();
|
||||||
if (originString != null) {
|
if (originString != null) {
|
||||||
origin = dateFieldMapper.parseToMilliseconds(originString);
|
origin = dateFieldMapper.fieldType().parseToMilliseconds(originString, false, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scaleString == null) {
|
if (scaleString == null) {
|
||||||
|
|
|
@ -157,7 +157,7 @@ public class MatchQuery {
|
||||||
final String field;
|
final String field;
|
||||||
FieldMapper mapper = parseContext.fieldMapper(fieldName);
|
FieldMapper mapper = parseContext.fieldMapper(fieldName);
|
||||||
if (mapper != null) {
|
if (mapper != null) {
|
||||||
field = mapper.names().indexName();
|
field = mapper.fieldType().names().indexName();
|
||||||
} else {
|
} else {
|
||||||
field = fieldName;
|
field = fieldName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,7 +165,7 @@ public class MultiMatchQuery extends MatchQuery {
|
||||||
FieldMapper mapper = parseContext.fieldMapper(name);
|
FieldMapper mapper = parseContext.fieldMapper(name);
|
||||||
if (mapper != null) {
|
if (mapper != null) {
|
||||||
Analyzer actualAnalyzer = getAnalyzer(mapper);
|
Analyzer actualAnalyzer = getAnalyzer(mapper);
|
||||||
name = mapper.names().indexName();
|
name = mapper.fieldType().names().indexName();
|
||||||
if (!groups.containsKey(actualAnalyzer)) {
|
if (!groups.containsKey(actualAnalyzer)) {
|
||||||
groups.put(actualAnalyzer, new ArrayList<FieldAndMapper>());
|
groups.put(actualAnalyzer, new ArrayList<FieldAndMapper>());
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
|
||||||
public class IndexedGeoBoundingBoxQuery {
|
public class IndexedGeoBoundingBoxQuery {
|
||||||
|
|
||||||
public static Query create(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
|
public static Query create(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
|
||||||
if (!fieldMapper.isEnableLatLon()) {
|
if (!fieldMapper.fieldType().isLatLonEnabled()) {
|
||||||
throw new IllegalArgumentException("lat/lon is not enabled (indexed) for field [" + fieldMapper.name() + "], can't use indexed filter on it");
|
throw new IllegalArgumentException("lat/lon is not enabled (indexed) for field [" + fieldMapper.name() + "], can't use indexed filter on it");
|
||||||
}
|
}
|
||||||
//checks to see if bounding box crosses 180 degrees
|
//checks to see if bounding box crosses 180 degrees
|
||||||
|
@ -45,16 +45,16 @@ public class IndexedGeoBoundingBoxQuery {
|
||||||
private static Query westGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
|
private static Query westGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
|
||||||
BooleanQuery filter = new BooleanQuery();
|
BooleanQuery filter = new BooleanQuery();
|
||||||
filter.setMinimumNumberShouldMatch(1);
|
filter.setMinimumNumberShouldMatch(1);
|
||||||
filter.add(fieldMapper.lonMapper().rangeFilter(null, bottomRight.lon(), true, true), Occur.SHOULD);
|
filter.add(fieldMapper.fieldType().lonFieldType().rangeQuery(null, bottomRight.lon(), true, true, null), Occur.SHOULD);
|
||||||
filter.add(fieldMapper.lonMapper().rangeFilter(topLeft.lon(), null, true, true), Occur.SHOULD);
|
filter.add(fieldMapper.fieldType().lonFieldType().rangeQuery(topLeft.lon(), null, true, true, null), Occur.SHOULD);
|
||||||
filter.add(fieldMapper.latMapper().rangeFilter(bottomRight.lat(), topLeft.lat(), true, true), Occur.MUST);
|
filter.add(fieldMapper.fieldType().latFieldType().rangeQuery(bottomRight.lat(), topLeft.lat(), true, true, null), Occur.MUST);
|
||||||
return new ConstantScoreQuery(filter);
|
return new ConstantScoreQuery(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Query eastGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
|
private static Query eastGeoBoundingBoxFilter(GeoPoint topLeft, GeoPoint bottomRight, GeoPointFieldMapper fieldMapper) {
|
||||||
BooleanQuery filter = new BooleanQuery();
|
BooleanQuery filter = new BooleanQuery();
|
||||||
filter.add(fieldMapper.lonMapper().rangeFilter(topLeft.lon(), bottomRight.lon(), true, true), Occur.MUST);
|
filter.add(fieldMapper.fieldType().lonFieldType().rangeQuery(topLeft.lon(), bottomRight.lon(), true, true, null), Occur.MUST);
|
||||||
filter.add(fieldMapper.latMapper().rangeFilter(bottomRight.lat(), topLeft.lat(), true, true), Occur.MUST);
|
filter.add(fieldMapper.fieldType().latFieldType().rangeQuery(bottomRight.lat(), topLeft.lat(), true, true, null), Occur.MUST);
|
||||||
return new ConstantScoreQuery(filter);
|
return new ConstantScoreQuery(filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ public class SimilarityService extends AbstractIndexComponent {
|
||||||
@Override
|
@Override
|
||||||
public Similarity get(String name) {
|
public Similarity get(String name) {
|
||||||
FieldMapper mapper = mapperService.smartNameFieldMapper(name);
|
FieldMapper mapper = mapperService.smartNameFieldMapper(name);
|
||||||
return (mapper != null && mapper.similarity() != null) ? mapper.similarity().get() : defaultSimilarity;
|
return (mapper != null && mapper.fieldType().similarity() != null) ? mapper.fieldType().similarity().get() : defaultSimilarity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,7 +236,7 @@ public class ShardTermVectorsService extends AbstractIndexShardComponent {
|
||||||
if (perFieldAnalyzer != null && perFieldAnalyzer.containsKey(field)) {
|
if (perFieldAnalyzer != null && perFieldAnalyzer.containsKey(field)) {
|
||||||
analyzer = mapperService.analysisService().analyzer(perFieldAnalyzer.get(field).toString());
|
analyzer = mapperService.analysisService().analyzer(perFieldAnalyzer.get(field).toString());
|
||||||
} else {
|
} else {
|
||||||
analyzer = mapperService.smartNameFieldMapper(field).indexAnalyzer();
|
analyzer = mapperService.smartNameFieldMapper(field).fieldType().indexAnalyzer();
|
||||||
}
|
}
|
||||||
if (analyzer == null) {
|
if (analyzer == null) {
|
||||||
analyzer = mapperService.analysisService().defaultIndexAnalyzer();
|
analyzer = mapperService.analysisService().defaultIndexAnalyzer();
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.IndexService;
|
import org.elasticsearch.index.IndexService;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.shard.ShardId;
|
import org.elasticsearch.index.shard.ShardId;
|
||||||
import org.elasticsearch.index.shard.ShardUtils;
|
import org.elasticsearch.index.shard.ShardUtils;
|
||||||
import org.elasticsearch.index.shard.IndexShard;
|
import org.elasticsearch.index.shard.IndexShard;
|
||||||
|
@ -99,7 +100,7 @@ public class IndicesFieldDataCache extends AbstractComponent implements RemovalL
|
||||||
this.closed = true;
|
this.closed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IndexFieldDataCache buildIndexFieldDataCache(IndexService indexService, Index index, FieldMapper.Names fieldNames, FieldDataType fieldDataType) {
|
public IndexFieldDataCache buildIndexFieldDataCache(IndexService indexService, Index index, MappedFieldType.Names fieldNames, FieldDataType fieldDataType) {
|
||||||
return new IndexFieldCache(logger, cache, indicesFieldDataCacheListener, indexService, index, fieldNames, fieldDataType);
|
return new IndexFieldCache(logger, cache, indicesFieldDataCacheListener, indexService, index, fieldNames, fieldDataType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,12 +140,12 @@ public class IndicesFieldDataCache extends AbstractComponent implements RemovalL
|
||||||
private final ESLogger logger;
|
private final ESLogger logger;
|
||||||
private final IndexService indexService;
|
private final IndexService indexService;
|
||||||
final Index index;
|
final Index index;
|
||||||
final FieldMapper.Names fieldNames;
|
final MappedFieldType.Names fieldNames;
|
||||||
final FieldDataType fieldDataType;
|
final FieldDataType fieldDataType;
|
||||||
private final Cache<Key, Accountable> cache;
|
private final Cache<Key, Accountable> cache;
|
||||||
private final IndicesFieldDataCacheListener indicesFieldDataCacheListener;
|
private final IndicesFieldDataCacheListener indicesFieldDataCacheListener;
|
||||||
|
|
||||||
IndexFieldCache(ESLogger logger,final Cache<Key, Accountable> cache, IndicesFieldDataCacheListener indicesFieldDataCacheListener, IndexService indexService, Index index, FieldMapper.Names fieldNames, FieldDataType fieldDataType) {
|
IndexFieldCache(ESLogger logger,final Cache<Key, Accountable> cache, IndicesFieldDataCacheListener indicesFieldDataCacheListener, IndexService indexService, Index index, MappedFieldType.Names fieldNames, FieldDataType fieldDataType) {
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.indexService = indexService;
|
this.indexService = indexService;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.index.fielddata.FieldDataType;
|
import org.elasticsearch.index.fielddata.FieldDataType;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,13 +44,14 @@ public class IndicesFieldDataCacheListener implements IndexFieldDataCache.Listen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad(FieldMapper.Names fieldNames, FieldDataType fieldDataType, Accountable fieldData) {
|
public void onLoad(MappedFieldType.Names fieldNames, FieldDataType fieldDataType, Accountable fieldData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUnload(FieldMapper.Names fieldNames, FieldDataType fieldDataType, boolean wasEvicted, long sizeInBytes) {
|
public void onUnload(MappedFieldType.Names fieldNames, FieldDataType fieldDataType, boolean wasEvicted, long sizeInBytes) {
|
||||||
assert sizeInBytes >= 0 : "When reducing circuit breaker, it should be adjusted with a number higher or equal to 0 and not [" + sizeInBytes + "]";
|
assert sizeInBytes >= 0 : "When reducing circuit breaker, it should be adjusted with a number higher or equal to 0 and not [" + sizeInBytes + "]";
|
||||||
circuitBreakerService.getBreaker(CircuitBreaker.FIELDDATA).addWithoutBreaking(-sizeInBytes);
|
circuitBreakerService.getBreaker(CircuitBreaker.FIELDDATA).addWithoutBreaking(-sizeInBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,8 +60,8 @@ class SingleDocumentPercolatorIndex implements PercolatorIndex {
|
||||||
if (tokenStream != null) {
|
if (tokenStream != null) {
|
||||||
memoryIndex.addField(field.name(), tokenStream, field.boost());
|
memoryIndex.addField(field.name(), tokenStream, field.boost());
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
throw new ElasticsearchException("Failed to create token stream", e);
|
throw new ElasticsearchException("Failed to create token stream for [" + field.name() + "]", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
context.initialize(new DocEngineSearcher(memoryIndex), parsedDocument);
|
context.initialize(new DocEngineSearcher(memoryIndex), parsedDocument);
|
||||||
|
|
|
@ -59,7 +59,7 @@ import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldDataService;
|
import org.elasticsearch.index.fielddata.IndexFieldDataService;
|
||||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper.Loading;
|
import org.elasticsearch.index.mapper.MappedFieldType.Loading;
|
||||||
import org.elasticsearch.index.mapper.MapperService;
|
import org.elasticsearch.index.mapper.MapperService;
|
||||||
import org.elasticsearch.index.query.TemplateQueryParser;
|
import org.elasticsearch.index.query.TemplateQueryParser;
|
||||||
import org.elasticsearch.index.search.stats.StatsGroupsParseElement;
|
import org.elasticsearch.index.search.stats.StatsGroupsParseElement;
|
||||||
|
@ -840,8 +840,12 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
final ObjectSet<String> warmUp = new ObjectHashSet<>();
|
final ObjectSet<String> warmUp = new ObjectHashSet<>();
|
||||||
for (DocumentMapper docMapper : mapperService.docMappers(false)) {
|
for (DocumentMapper docMapper : mapperService.docMappers(false)) {
|
||||||
for (FieldMapper fieldMapper : docMapper.mappers()) {
|
for (FieldMapper fieldMapper : docMapper.mappers()) {
|
||||||
final String indexName = fieldMapper.names().indexName();
|
final String indexName = fieldMapper.fieldType().names().indexName();
|
||||||
if (fieldMapper.fieldType().indexOptions() != IndexOptions.NONE && !fieldMapper.fieldType().omitNorms() && fieldMapper.normsLoading(defaultLoading) == Loading.EAGER) {
|
Loading normsLoading = fieldMapper.fieldType().normsLoading();
|
||||||
|
if (normsLoading == null) {
|
||||||
|
normsLoading = defaultLoading;
|
||||||
|
}
|
||||||
|
if (fieldMapper.fieldType().indexOptions() != IndexOptions.NONE && !fieldMapper.fieldType().omitNorms() && normsLoading == Loading.EAGER) {
|
||||||
warmUp.add(indexName);
|
warmUp.add(indexName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -896,7 +900,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
final Map<String, FieldMapper> warmUp = new HashMap<>();
|
final Map<String, FieldMapper> warmUp = new HashMap<>();
|
||||||
for (DocumentMapper docMapper : mapperService.docMappers(false)) {
|
for (DocumentMapper docMapper : mapperService.docMappers(false)) {
|
||||||
for (FieldMapper fieldMapper : docMapper.mappers()) {
|
for (FieldMapper fieldMapper : docMapper.mappers()) {
|
||||||
final FieldDataType fieldDataType = fieldMapper.fieldDataType();
|
final FieldDataType fieldDataType = fieldMapper.fieldType().fieldDataType();
|
||||||
if (fieldDataType == null) {
|
if (fieldDataType == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -904,7 +908,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String indexName = fieldMapper.names().indexName();
|
final String indexName = fieldMapper.fieldType().names().indexName();
|
||||||
if (warmUp.containsKey(indexName)) {
|
if (warmUp.containsKey(indexName)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -924,10 +928,10 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
final long start = System.nanoTime();
|
final long start = System.nanoTime();
|
||||||
indexFieldDataService.getForField(fieldMapper).load(ctx);
|
indexFieldDataService.getForField(fieldMapper).load(ctx);
|
||||||
if (indexShard.warmerService().logger().isTraceEnabled()) {
|
if (indexShard.warmerService().logger().isTraceEnabled()) {
|
||||||
indexShard.warmerService().logger().trace("warmed fielddata for [{}], took [{}]", fieldMapper.names().fullName(), TimeValue.timeValueNanos(System.nanoTime() - start));
|
indexShard.warmerService().logger().trace("warmed fielddata for [{}], took [{}]", fieldMapper.fieldType().names().fullName(), TimeValue.timeValueNanos(System.nanoTime() - start));
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
indexShard.warmerService().logger().warn("failed to warm-up fielddata for [{}]", t, fieldMapper.names().fullName());
|
indexShard.warmerService().logger().warn("failed to warm-up fielddata for [{}]", t, fieldMapper.fieldType().names().fullName());
|
||||||
} finally {
|
} finally {
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
@ -950,14 +954,14 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
final Map<String, FieldMapper> warmUpGlobalOrdinals = new HashMap<>();
|
final Map<String, FieldMapper> warmUpGlobalOrdinals = new HashMap<>();
|
||||||
for (DocumentMapper docMapper : mapperService.docMappers(false)) {
|
for (DocumentMapper docMapper : mapperService.docMappers(false)) {
|
||||||
for (FieldMapper fieldMapper : docMapper.mappers()) {
|
for (FieldMapper fieldMapper : docMapper.mappers()) {
|
||||||
final FieldDataType fieldDataType = fieldMapper.fieldDataType();
|
final FieldDataType fieldDataType = fieldMapper.fieldType().fieldDataType();
|
||||||
if (fieldDataType == null) {
|
if (fieldDataType == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (fieldDataType.getLoading() != Loading.EAGER_GLOBAL_ORDINALS) {
|
if (fieldDataType.getLoading() != Loading.EAGER_GLOBAL_ORDINALS) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final String indexName = fieldMapper.names().indexName();
|
final String indexName = fieldMapper.fieldType().names().indexName();
|
||||||
if (warmUpGlobalOrdinals.containsKey(indexName)) {
|
if (warmUpGlobalOrdinals.containsKey(indexName)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -976,10 +980,10 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
|
||||||
IndexFieldData.Global ifd = indexFieldDataService.getForField(fieldMapper);
|
IndexFieldData.Global ifd = indexFieldDataService.getForField(fieldMapper);
|
||||||
ifd.loadGlobal(context.reader());
|
ifd.loadGlobal(context.reader());
|
||||||
if (indexShard.warmerService().logger().isTraceEnabled()) {
|
if (indexShard.warmerService().logger().isTraceEnabled()) {
|
||||||
indexShard.warmerService().logger().trace("warmed global ordinals for [{}], took [{}]", fieldMapper.names().fullName(), TimeValue.timeValueNanos(System.nanoTime() - start));
|
indexShard.warmerService().logger().trace("warmed global ordinals for [{}], took [{}]", fieldMapper.fieldType().names().fullName(), TimeValue.timeValueNanos(System.nanoTime() - start));
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
indexShard.warmerService().logger().warn("failed to warm-up global ordinals for [{}]", t, fieldMapper.names().fullName());
|
indexShard.warmerService().logger().warn("failed to warm-up global ordinals for [{}]", t, fieldMapper.fieldType().names().fullName());
|
||||||
} finally {
|
} finally {
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ public class ChildrenParser implements Aggregator.Parser {
|
||||||
parentFilter = new QueryWrapperFilter(parentDocMapper.typeFilter());
|
parentFilter = new QueryWrapperFilter(parentDocMapper.typeFilter());
|
||||||
childFilter = new QueryWrapperFilter(childDocMapper.typeFilter());
|
childFilter = new QueryWrapperFilter(childDocMapper.typeFilter());
|
||||||
ParentChildIndexFieldData parentChildIndexFieldData = context.fieldData().getForField(parentFieldMapper);
|
ParentChildIndexFieldData parentChildIndexFieldData = context.fieldData().getForField(parentFieldMapper);
|
||||||
config.fieldContext(new FieldContext(parentFieldMapper.names().indexName(), parentChildIndexFieldData, parentFieldMapper));
|
config.fieldContext(new FieldContext(parentFieldMapper.fieldType().names().indexName(), parentChildIndexFieldData, parentFieldMapper));
|
||||||
} else {
|
} else {
|
||||||
config.unmapped(true);
|
config.unmapped(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ public class AggregationContext {
|
||||||
if (config.fieldContext != null && config.fieldContext.mapper() instanceof DateFieldMapper) {
|
if (config.fieldContext != null && config.fieldContext.mapper() instanceof DateFieldMapper) {
|
||||||
final DateFieldMapper mapper = (DateFieldMapper) config.fieldContext.mapper();
|
final DateFieldMapper mapper = (DateFieldMapper) config.fieldContext.mapper();
|
||||||
try {
|
try {
|
||||||
missing = mapper.dateTimeFormatter().parser().parseDateTime(config.missing.toString()).getMillis();
|
missing = mapper.fieldType().dateTimeFormatter().parser().parseDateTime(config.missing.toString()).getMillis();
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new SearchParseException(context, "Expected a date value in [missing] but got [" + config.missing + "]", null, e);
|
throw new SearchParseException(context, "Expected a date value in [missing] but got [" + config.missing + "]", null, e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class ValueFormat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DateTime mapper(DateFieldMapper mapper) {
|
public static DateTime mapper(DateFieldMapper mapper) {
|
||||||
return new DateTime(mapper.dateTimeFormatter().format(), ValueFormatter.DateTime.mapper(mapper), ValueParser.DateMath.mapper(mapper));
|
return new DateTime(mapper.fieldType().dateTimeFormatter().format(), ValueFormatter.DateTime.mapper(mapper), ValueParser.DateMath.mapper(mapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
public DateTime(String pattern, ValueFormatter formatter, ValueParser parser) {
|
public DateTime(String pattern, ValueFormatter formatter, ValueParser parser) {
|
||||||
|
|
|
@ -105,7 +105,7 @@ public interface ValueFormatter extends Streamable {
|
||||||
private DateTimeZone timeZone = DateTimeZone.UTC;
|
private DateTimeZone timeZone = DateTimeZone.UTC;
|
||||||
|
|
||||||
public static DateTime mapper(DateFieldMapper mapper) {
|
public static DateTime mapper(DateFieldMapper mapper) {
|
||||||
return new DateTime(mapper.dateTimeFormatter());
|
return new DateTime(mapper.fieldType().dateTimeFormatter());
|
||||||
}
|
}
|
||||||
|
|
||||||
static final byte ID = 2;
|
static final byte ID = 2;
|
||||||
|
|
|
@ -110,7 +110,7 @@ public interface ValueParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DateMath mapper(DateFieldMapper mapper) {
|
public static DateMath mapper(DateFieldMapper mapper) {
|
||||||
return new DateMath(new DateMathParser(mapper.dateTimeFormatter(), DateFieldMapper.Defaults.TIME_UNIT));
|
return new DateMath(new DateMathParser(mapper.fieldType().dateTimeFormatter(), DateFieldMapper.Defaults.TIME_UNIT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ public class FetchPhase implements SearchPhase {
|
||||||
if (fieldNames == null) {
|
if (fieldNames == null) {
|
||||||
fieldNames = new HashSet<>();
|
fieldNames = new HashSet<>();
|
||||||
}
|
}
|
||||||
fieldNames.add(mapper.names().indexName());
|
fieldNames.add(mapper.fieldType().names().indexName());
|
||||||
} else {
|
} else {
|
||||||
if (extractFieldNames == null) {
|
if (extractFieldNames == null) {
|
||||||
extractFieldNames = newArrayList();
|
extractFieldNames = newArrayList();
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue