better type based inference when using scripts

This commit is contained in:
Shay Banon 2012-06-23 17:25:02 +02:00
parent df62e39d20
commit efe85f322a
8 changed files with 73 additions and 17 deletions

View File

@ -193,7 +193,7 @@ public class ShardGetService extends AbstractIndexShardComponent {
Object value = null;
if (field.contains("_source.") || field.contains("doc[")) {
if (searchLookup == null) {
searchLookup = new SearchLookup(mapperService, indexCache.fieldData());
searchLookup = new SearchLookup(mapperService, indexCache.fieldData(), new String[]{type});
}
SearchScript searchScript = scriptService.search(searchLookup, "mvel", field, null);
searchScript.setNextReader(docIdAndVersion.reader);
@ -211,7 +211,7 @@ public class ShardGetService extends AbstractIndexShardComponent {
FieldMappers x = docMapper.mappers().smartName(field);
if (x == null || !x.mapper().stored()) {
if (searchLookup == null) {
searchLookup = new SearchLookup(mapperService, indexCache.fieldData());
searchLookup = new SearchLookup(mapperService, indexCache.fieldData(), new String[]{type});
searchLookup.setNextReader(docIdAndVersion.reader);
searchLookup.setNextDocId(docIdAndVersion.docId);
}
@ -271,7 +271,7 @@ public class ShardGetService extends AbstractIndexShardComponent {
} else {
if (field.contains("_source.")) {
if (searchLookup == null) {
searchLookup = new SearchLookup(mapperService, indexCache.fieldData());
searchLookup = new SearchLookup(mapperService, indexCache.fieldData(), new String[]{type});
}
if (sourceAsMap == null) {
sourceAsMap = SourceLookup.sourceAsMap(source.source.bytes(), source.source.offset(), source.source.length());
@ -294,7 +294,7 @@ public class ShardGetService extends AbstractIndexShardComponent {
}
} else {
if (searchLookup == null) {
searchLookup = new SearchLookup(mapperService, indexCache.fieldData());
searchLookup = new SearchLookup(mapperService, indexCache.fieldData(), new String[]{type});
searchLookup.source().setNextSource(source.source.bytes(), source.source.offset(), source.source.length());
}

View File

@ -43,6 +43,13 @@ public class GeoPointDocFieldData extends DocFieldData<GeoPointFieldData> {
return fieldData.factorDistance(docId, DistanceUnit.MILES, lat, lon);
}
public double factorDistanceWithDefault(double lat, double lon, double defaultValue) {
if (!fieldData.hasValue(docId)) {
return defaultValue;
}
return fieldData.factorDistance(docId, DistanceUnit.MILES, lat, lon);
}
public double factorDistance02(double lat, double lon) {
return fieldData.factorDistance(docId, DistanceUnit.MILES, lat, lon) + 1;
}
@ -55,22 +62,57 @@ public class GeoPointDocFieldData extends DocFieldData<GeoPointFieldData> {
return fieldData.arcDistance(docId, DistanceUnit.MILES, lat, lon);
}
public double arcDistanceWithDefault(double lat, double lon, double defaultValue) {
if (!fieldData.hasValue(docId)) {
return defaultValue;
}
return fieldData.arcDistance(docId, DistanceUnit.MILES, lat, lon);
}
public double arcDistanceInKm(double lat, double lon) {
return fieldData.arcDistance(docId, DistanceUnit.KILOMETERS, lat, lon);
}
public double arcDistanceInKmWithDefault(double lat, double lon, double defaultValue) {
if (!fieldData.hasValue(docId)) {
return defaultValue;
}
return fieldData.arcDistance(docId, DistanceUnit.KILOMETERS, lat, lon);
}
public double distance(double lat, double lon) {
return fieldData.distance(docId, DistanceUnit.MILES, lat, lon);
}
public double distanceWithDefault(double lat, double lon, double defaultValue) {
if (!fieldData.hasValue(docId)) {
return defaultValue;
}
return fieldData.distance(docId, DistanceUnit.MILES, lat, lon);
}
public double distanceInKm(double lat, double lon) {
return fieldData.distance(docId, DistanceUnit.KILOMETERS, lat, lon);
}
public double distanceInKmWithDefault(double lat, double lon, double defaultValue) {
if (!fieldData.hasValue(docId)) {
return defaultValue;
}
return fieldData.distance(docId, DistanceUnit.KILOMETERS, lat, lon);
}
public double geohashDistance(String geohash) {
return fieldData.distanceGeohash(docId, DistanceUnit.MILES, geohash);
}
public double geohashDistanceWithDefault(String geohash, double defaultValue) {
if (!fieldData.hasValue(docId)) {
return defaultValue;
}
return fieldData.distanceGeohash(docId, DistanceUnit.MILES, geohash);
}
public double geohashDistanceInKm(String geohash) {
return fieldData.distanceGeohash(docId, DistanceUnit.KILOMETERS, geohash);
}

View File

@ -290,7 +290,7 @@ public class QueryParseContext {
return current.lookup();
}
if (lookup == null) {
lookup = new SearchLookup(mapperService(), indexCache().fieldData());
lookup = new SearchLookup(mapperService(), indexCache().fieldData(), null);
}
return lookup;
}

View File

@ -180,7 +180,7 @@ public class ScriptService extends AbstractComponent {
}
public SearchScript search(MapperService mapperService, FieldDataCache fieldDataCache, String lang, String script, @Nullable Map<String, Object> vars) {
return search(compile(lang, script), new SearchLookup(mapperService, fieldDataCache), vars);
return search(compile(lang, script), new SearchLookup(mapperService, fieldDataCache, null), vars);
}
public Object execute(CompiledScript compiledScript, Map vars) {

View File

@ -520,8 +520,9 @@ public class SearchContext implements Releasable {
}
public SearchLookup lookup() {
// TODO: The types should take into account the parsing context in QueryParserContext...
if (searchLookup == null) {
searchLookup = new SearchLookup(mapperService(), fieldDataCache());
searchLookup = new SearchLookup(mapperService(), fieldDataCache(), request.types());
}
return searchLookup;
}

View File

@ -24,6 +24,7 @@ import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Scorer;
import org.elasticsearch.ElasticSearchException;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.index.cache.field.data.FieldDataCache;
import org.elasticsearch.index.field.data.DocFieldData;
import org.elasticsearch.index.field.data.FieldData;
@ -32,6 +33,7 @@ import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.MapperService;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
@ -47,15 +49,19 @@ public class DocLookup implements Map {
private final FieldDataCache fieldDataCache;
@Nullable
private final String[] types;
private IndexReader reader;
private Scorer scorer;
private int docId = -1;
DocLookup(MapperService mapperService, FieldDataCache fieldDataCache) {
DocLookup(MapperService mapperService, FieldDataCache fieldDataCache, @Nullable String[] types) {
this.mapperService = mapperService;
this.fieldDataCache = fieldDataCache;
this.types = types;
}
public MapperService mapperService() {
@ -105,9 +111,9 @@ public class DocLookup implements Map {
String fieldName = key.toString();
FieldData fieldData = localCacheFieldData.get(fieldName);
if (fieldData == null) {
FieldMapper mapper = mapperService.smartNameFieldMapper(fieldName);
FieldMapper mapper = mapperService.smartNameFieldMapper(fieldName, types);
if (mapper == null) {
throw new ElasticSearchIllegalArgumentException("No field found for [" + fieldName + "]");
throw new ElasticSearchIllegalArgumentException("No field found for [" + fieldName + "] in mapping with types " + Arrays.toString(types) + "");
}
try {
fieldData = fieldDataCache.cache(mapper.fieldDataType(), reader, mapper.names().indexName());
@ -124,7 +130,7 @@ public class DocLookup implements Map {
String fieldName = key.toString();
FieldData fieldData = localCacheFieldData.get(fieldName);
if (fieldData == null) {
FieldMapper mapper = mapperService.smartNameFieldMapper(fieldName);
FieldMapper mapper = mapperService.smartNameFieldMapper(fieldName, types);
if (mapper == null) {
return false;
}

View File

@ -23,11 +23,13 @@ import com.google.common.collect.Maps;
import org.apache.lucene.index.IndexReader;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.ElasticSearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.lucene.document.SingleFieldSelector;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.MapperService;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
@ -39,6 +41,9 @@ public class FieldsLookup implements Map {
private final MapperService mapperService;
@Nullable
private final String[] types;
private IndexReader reader;
private int docId = -1;
@ -47,8 +52,9 @@ public class FieldsLookup implements Map {
private final SingleFieldSelector fieldSelector = new SingleFieldSelector();
FieldsLookup(MapperService mapperService) {
FieldsLookup(MapperService mapperService, @Nullable String[] types) {
this.mapperService = mapperService;
this.types = types;
}
public void setNextReader(IndexReader reader) {
@ -137,9 +143,9 @@ public class FieldsLookup implements Map {
private FieldLookup loadFieldData(String name) {
FieldLookup data = cachedFieldData.get(name);
if (data == null) {
FieldMapper mapper = mapperService.smartNameFieldMapper(name);
FieldMapper mapper = mapperService.smartNameFieldMapper(name, types);
if (mapper == null) {
throw new ElasticSearchIllegalArgumentException("No field found for [" + name + "]");
throw new ElasticSearchIllegalArgumentException("No field found for [" + name + "] in mapping with types " + Arrays.toString(types) + "");
}
data = new FieldLookup(mapper);
cachedFieldData.put(name, data);

View File

@ -22,6 +22,7 @@ package org.elasticsearch.search.lookup;
import com.google.common.collect.ImmutableMap;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Scorer;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.index.cache.field.data.FieldDataCache;
import org.elasticsearch.index.mapper.MapperService;
@ -38,10 +39,10 @@ public class SearchLookup {
final ImmutableMap<String, Object> asMap;
public SearchLookup(MapperService mapperService, FieldDataCache fieldDataCache) {
docMap = new DocLookup(mapperService, fieldDataCache);
public SearchLookup(MapperService mapperService, FieldDataCache fieldDataCache, @Nullable String[] types) {
docMap = new DocLookup(mapperService, fieldDataCache, types);
sourceLookup = new SourceLookup();
fieldsLookup = new FieldsLookup(mapperService);
fieldsLookup = new FieldsLookup(mapperService, types);
asMap = ImmutableMap.<String, Object>of("doc", docMap, "_doc", docMap, "_source", sourceLookup, "_fields", fieldsLookup);
}