diff --git a/build.gradle b/build.gradle
index be47690d8eb..b419bf01e15 100644
--- a/build.gradle
+++ b/build.gradle
@@ -223,6 +223,10 @@ tasks.idea.dependsOn(buildSrcIdea)
// eclipse configuration
allprojects {
apply plugin: 'eclipse'
+ // Name all the non-root projects after their path so that paths get grouped together when imported into eclipse.
+ if (path != ':') {
+ eclipse.project.name = path
+ }
plugins.withType(JavaBasePlugin) {
File eclipseBuild = project.file('build-eclipse')
diff --git a/buildSrc/src/main/resources/checkstyle_suppressions.xml b/buildSrc/src/main/resources/checkstyle_suppressions.xml
index b824ad94998..9ad9e746b9c 100644
--- a/buildSrc/src/main/resources/checkstyle_suppressions.xml
+++ b/buildSrc/src/main/resources/checkstyle_suppressions.xml
@@ -649,8 +649,6 @@
-
-
@@ -662,9 +660,6 @@
-
-
-
@@ -1309,7 +1304,6 @@
-
diff --git a/buildSrc/version.properties b/buildSrc/version.properties
index 1c5b1e724fd..110765d3535 100644
--- a/buildSrc/version.properties
+++ b/buildSrc/version.properties
@@ -1,5 +1,5 @@
elasticsearch = 3.0.0-SNAPSHOT
-lucene = 5.5.0-snapshot-4de5f1d
+lucene = 5.5.0-snapshot-850c6c2
# optional dependencies
spatial4j = 0.5
diff --git a/core/src/main/java/org/elasticsearch/action/admin/indices/cache/clear/TransportClearIndicesCacheAction.java b/core/src/main/java/org/elasticsearch/action/admin/indices/cache/clear/TransportClearIndicesCacheAction.java
index 16002d36448..bc229d72b1b 100644
--- a/core/src/main/java/org/elasticsearch/action/admin/indices/cache/clear/TransportClearIndicesCacheAction.java
+++ b/core/src/main/java/org/elasticsearch/action/admin/indices/cache/clear/TransportClearIndicesCacheAction.java
@@ -35,7 +35,6 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.shard.IndexShard;
import org.elasticsearch.indices.IndicesService;
-import org.elasticsearch.indices.cache.request.IndicesRequestCache;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
@@ -98,7 +97,7 @@ public class TransportClearIndicesCacheAction extends TransportBroadcastByNodeAc
}
if (request.requestCache()) {
clearedAtLeastOne = true;
- indicesService.getIndicesRequestCache().clear(shard);
+ indicesService.clearRequestCache(shard);
}
if (request.recycler()) {
logger.debug("Clear CacheRecycler on index [{}]", service.index());
@@ -114,7 +113,7 @@ public class TransportClearIndicesCacheAction extends TransportBroadcastByNodeAc
} else {
service.cache().clear("api");
service.fieldData().clear();
- indicesService.getIndicesRequestCache().clear(shard);
+ indicesService.clearRequestCache(shard);
}
}
}
diff --git a/core/src/main/java/org/elasticsearch/action/admin/indices/stats/CommonStats.java b/core/src/main/java/org/elasticsearch/action/admin/indices/stats/CommonStats.java
index 47fb8d8356a..c1c29780a47 100644
--- a/core/src/main/java/org/elasticsearch/action/admin/indices/stats/CommonStats.java
+++ b/core/src/main/java/org/elasticsearch/action/admin/indices/stats/CommonStats.java
@@ -26,7 +26,6 @@ import org.elasticsearch.common.io.stream.Streamable;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.cache.query.QueryCacheStats;
import org.elasticsearch.index.cache.request.RequestCacheStats;
import org.elasticsearch.index.engine.SegmentsStats;
@@ -41,13 +40,11 @@ import org.elasticsearch.index.refresh.RefreshStats;
import org.elasticsearch.index.search.stats.SearchStats;
import org.elasticsearch.index.shard.DocsStats;
import org.elasticsearch.index.shard.IndexShard;
-import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.store.StoreStats;
import org.elasticsearch.index.suggest.stats.SuggestStats;
import org.elasticsearch.index.translog.TranslogStats;
import org.elasticsearch.index.warmer.WarmerStats;
-import org.elasticsearch.indices.IndicesService;
-import org.elasticsearch.indices.cache.query.IndicesQueryCache;
+import org.elasticsearch.indices.IndicesQueryCache;
import org.elasticsearch.search.suggest.completion.CompletionStats;
import java.io.IOException;
diff --git a/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java b/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
index 70e9ca85ee7..004b0541eee 100644
--- a/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
+++ b/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
@@ -175,7 +175,7 @@ final class Bootstrap {
JarHell.checkJarHell();
// install SM after natives, shutdown hooks, etc.
- setupSecurity(settings, environment);
+ Security.configure(environment, BootstrapSettings.SECURITY_FILTER_BAD_DEFAULTS_SETTING.get(settings));
// We do not need to reload system properties here as we have already applied them in building the settings and
// reloading could cause multiple prompts to the user for values if a system property was specified with a prompt
@@ -188,14 +188,6 @@ final class Bootstrap {
node = new Node(nodeSettings);
}
-
-
- private void setupSecurity(Settings settings, Environment environment) throws Exception {
- if (BootstrapSettings.SECURITY_MANAGER_ENABLED_SETTING.get(settings)) {
- Security.configure(environment, BootstrapSettings.SECURITY_FILTER_BAD_DEFAULTS_SETTING.get(settings));
- }
- }
-
@SuppressForbidden(reason = "Exception#printStackTrace()")
private static void setupLogging(Settings settings, Environment environment) {
try {
diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java
index 9122504f0e8..a20ff9bb059 100644
--- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java
+++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapSettings.java
@@ -27,14 +27,6 @@ public final class BootstrapSettings {
private BootstrapSettings() {
}
- // TODO: remove this: http://www.openbsd.org/papers/hackfest2015-pledge/mgp00005.jpg
- /**
- * option to turn off our security manager completely, for example
- * if you want to have your own configuration or just disable
- */
- public static final Setting SECURITY_MANAGER_ENABLED_SETTING =
- Setting.boolSetting("security.manager.enabled", true, false, Scope.CLUSTER);
-
// TODO: remove this hack when insecure defaults are removed from java
public static final Setting SECURITY_FILTER_BAD_DEFAULTS_SETTING =
Setting.boolSetting("security.manager.filter_bad_defaults", true, false, Scope.CLUSTER);
diff --git a/core/src/main/java/org/elasticsearch/common/geo/GeoPoint.java b/core/src/main/java/org/elasticsearch/common/geo/GeoPoint.java
index 513a7977d67..e233c84f47c 100644
--- a/core/src/main/java/org/elasticsearch/common/geo/GeoPoint.java
+++ b/core/src/main/java/org/elasticsearch/common/geo/GeoPoint.java
@@ -20,8 +20,11 @@
package org.elasticsearch.common.geo;
import org.apache.lucene.util.BitUtil;
-import org.apache.lucene.util.GeoHashUtils;
-import org.apache.lucene.util.GeoUtils;
+
+import static org.apache.lucene.spatial.util.GeoHashUtils.mortonEncode;
+import static org.apache.lucene.spatial.util.GeoHashUtils.stringEncode;
+import static org.apache.lucene.spatial.util.GeoEncodingUtils.mortonUnhashLat;
+import static org.apache.lucene.spatial.util.GeoEncodingUtils.mortonUnhashLon;
/**
*
@@ -81,14 +84,14 @@ public final class GeoPoint {
}
public GeoPoint resetFromIndexHash(long hash) {
- lon = GeoUtils.mortonUnhashLon(hash);
- lat = GeoUtils.mortonUnhashLat(hash);
+ lon = mortonUnhashLon(hash);
+ lat = mortonUnhashLat(hash);
return this;
}
public GeoPoint resetFromGeoHash(String geohash) {
- final long hash = GeoHashUtils.mortonEncode(geohash);
- return this.reset(GeoUtils.mortonUnhashLat(hash), GeoUtils.mortonUnhashLon(hash));
+ final long hash = mortonEncode(geohash);
+ return this.reset(mortonUnhashLat(hash), mortonUnhashLon(hash));
}
public GeoPoint resetFromGeoHash(long geohashLong) {
@@ -113,11 +116,11 @@ public final class GeoPoint {
}
public final String geohash() {
- return GeoHashUtils.stringEncode(lon, lat);
+ return stringEncode(lon, lat);
}
public final String getGeohash() {
- return GeoHashUtils.stringEncode(lon, lat);
+ return stringEncode(lon, lat);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/common/geo/GeoUtils.java b/core/src/main/java/org/elasticsearch/common/geo/GeoUtils.java
index c5c36b5b0c2..a0d74f993a5 100644
--- a/core/src/main/java/org/elasticsearch/common/geo/GeoUtils.java
+++ b/core/src/main/java/org/elasticsearch/common/geo/GeoUtils.java
@@ -21,7 +21,6 @@ package org.elasticsearch.common.geo;
import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
-import org.apache.lucene.util.GeoDistanceUtils;
import org.apache.lucene.util.SloppyMath;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.unit.DistanceUnit;
@@ -29,6 +28,8 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentParser.Token;
import org.elasticsearch.index.mapper.geo.GeoPointFieldMapper;
+import static org.apache.lucene.spatial.util.GeoDistanceUtils.maxRadialDistanceMeters;
+
import java.io.IOException;
/**
@@ -70,7 +71,7 @@ public class GeoUtils {
* maximum distance/radius from the point 'center' before overlapping
**/
public static double maxRadialDistance(GeoPoint center, double initialRadius) {
- final double maxRadius = GeoDistanceUtils.maxRadialDistanceMeters(center.lon(), center.lat());
+ final double maxRadius = maxRadialDistanceMeters(center.lon(), center.lat());
return Math.min(initialRadius, maxRadius);
}
diff --git a/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java b/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java
index 142fbacfb01..d68e43ea1cb 100644
--- a/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java
+++ b/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java
@@ -65,8 +65,8 @@ import org.elasticsearch.index.store.IndexStoreConfig;
import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.indices.analysis.HunspellService;
import org.elasticsearch.indices.breaker.HierarchyCircuitBreakerService;
-import org.elasticsearch.indices.cache.query.IndicesQueryCache;
-import org.elasticsearch.indices.cache.request.IndicesRequestCache;
+import org.elasticsearch.indices.IndicesQueryCache;
+import org.elasticsearch.indices.IndicesRequestCache;
import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
import org.elasticsearch.indices.recovery.RecoverySettings;
import org.elasticsearch.indices.store.IndicesStore;
@@ -307,11 +307,10 @@ public final class ClusterSettings extends AbstractScopedSettings {
ScriptService.SCRIPT_CACHE_SIZE_SETTING,
ScriptService.SCRIPT_CACHE_EXPIRE_SETTING,
ScriptService.SCRIPT_AUTO_RELOAD_ENABLED_SETTING,
- IndicesService.INDICES_FIELDDATA_CLEAN_INTERVAL_SETTING,
+ IndicesService.INDICES_CACHE_CLEAN_INTERVAL_SETTING,
IndicesFieldDataCache.INDICES_FIELDDATA_CACHE_SIZE_KEY,
IndicesRequestCache.INDICES_CACHE_QUERY_SIZE,
IndicesRequestCache.INDICES_CACHE_QUERY_EXPIRE,
- IndicesRequestCache.INDICES_CACHE_REQUEST_CLEAN_INTERVAL,
HunspellService.HUNSPELL_LAZY_LOAD,
HunspellService.HUNSPELL_IGNORE_CASE,
HunspellService.HUNSPELL_DICTIONARY_OPTIONS,
@@ -395,7 +394,6 @@ public final class ClusterSettings extends AbstractScopedSettings {
PageCacheRecycler.WEIGHT_OBJECTS_SETTING,
PageCacheRecycler.TYPE_SETTING,
PluginsService.MANDATORY_SETTING,
- BootstrapSettings.SECURITY_MANAGER_ENABLED_SETTING,
BootstrapSettings.SECURITY_FILTER_BAD_DEFAULTS_SETTING,
BootstrapSettings.MLOCKALL_SETTING,
BootstrapSettings.SECCOMP_SETTING,
diff --git a/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java b/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java
index 157bbfbd5b9..69ef795812d 100644
--- a/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java
+++ b/core/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java
@@ -39,7 +39,7 @@ import org.elasticsearch.index.store.FsDirectoryService;
import org.elasticsearch.index.store.IndexStore;
import org.elasticsearch.index.store.Store;
import org.elasticsearch.index.IndexWarmer;
-import org.elasticsearch.indices.cache.request.IndicesRequestCache;
+import org.elasticsearch.indices.IndicesRequestCache;
import java.util.Arrays;
import java.util.Collections;
diff --git a/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java b/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java
index 23c67609f1b..b06f53459c8 100644
--- a/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java
+++ b/core/src/main/java/org/elasticsearch/common/settings/SettingsModule.java
@@ -20,7 +20,6 @@
package org.elasticsearch.common.settings;
import org.elasticsearch.common.inject.AbstractModule;
-import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.tribe.TribeService;
import java.util.HashMap;
@@ -90,7 +89,7 @@ public class SettingsModule extends AbstractModule {
/**
* Registers a settings filter pattern that allows to filter out certain settings that for instance contain sensitive information
- * or if a setting is for internal purposes only. The given patter must either be a valid settings key or a simple regesp pattern.
+ * or if a setting is for internal purposes only. The given pattern must either be a valid settings key or a simple regexp pattern.
*/
public void registerSettingsFilter(String filter) {
if (SettingsFilter.isValidPattern(filter) == false) {
@@ -103,11 +102,23 @@ public class SettingsModule extends AbstractModule {
}
public void registerSettingsFilterIfMissing(String filter) {
- if (settingsFilterPattern.contains(filter)) {
+ if (settingsFilterPattern.contains(filter) == false) {
registerSettingsFilter(filter);
}
}
+ /**
+ * Check if a setting has already been registered
+ */
+ public boolean exists(Setting> setting) {
+ switch (setting.getScope()) {
+ case CLUSTER:
+ return clusterSettings.containsKey(setting.getKey());
+ case INDEX:
+ return indexSettings.containsKey(setting.getKey());
+ }
+ throw new IllegalArgumentException("setting scope is unknown. This should never happen!");
+ }
private void validateTribeSettings(Settings settings, ClusterSettings clusterSettings) {
Map groups = settings.filter(TRIBE_CLIENT_NODE_SETTINGS_PREDICATE).getGroups("tribe.", true);
diff --git a/core/src/main/java/org/elasticsearch/common/util/CancellableThreads.java b/core/src/main/java/org/elasticsearch/common/util/CancellableThreads.java
index d45afead715..b6edb2db8da 100644
--- a/core/src/main/java/org/elasticsearch/common/util/CancellableThreads.java
+++ b/core/src/main/java/org/elasticsearch/common/util/CancellableThreads.java
@@ -80,14 +80,32 @@ public class CancellableThreads {
* @param interruptable code to run
*/
public void execute(Interruptable interruptable) {
+ try {
+ executeIO(interruptable);
+ } catch (IOException e) {
+ assert false : "the passed interruptable can not result in an IOException";
+ throw new RuntimeException("unexpected IO exception", e);
+ }
+ }
+ /**
+ * run the Interruptable, capturing the executing thread. Concurrent calls to {@link #cancel(String)} will interrupt this thread
+ * causing the call to prematurely return.
+ *
+ * @param interruptable code to run
+ */
+ public void executeIO(IOInterruptable interruptable) throws IOException {
boolean wasInterrupted = add();
- RuntimeException throwable = null;
+ RuntimeException runtimeException = null;
+ IOException ioException = null;
+
try {
interruptable.run();
} catch (InterruptedException | ThreadInterruptedException e) {
// assume this is us and ignore
} catch (RuntimeException t) {
- throwable = t;
+ runtimeException = t;
+ } catch (IOException e) {
+ ioException = e;
} finally {
remove();
}
@@ -101,10 +119,14 @@ public class CancellableThreads {
}
synchronized (this) {
if (isCancelled()) {
- onCancel(reason, throwable);
- } else if (throwable != null) {
+ onCancel(reason, ioException != null ? ioException : runtimeException);
+ } else if (ioException != null) {
// if we're not canceling, we throw the original exception
- throw throwable;
+ throw ioException;
+ }
+ if (runtimeException != null) {
+ // if we're not canceling, we throw the original exception
+ throw runtimeException;
}
}
}
@@ -131,10 +153,14 @@ public class CancellableThreads {
}
- public interface Interruptable {
+ public interface Interruptable extends IOInterruptable {
void run() throws InterruptedException;
}
+ public interface IOInterruptable {
+ void run() throws IOException, InterruptedException;
+ }
+
public static class ExecutionCancelledException extends ElasticsearchException {
public ExecutionCancelledException(String msg) {
diff --git a/core/src/main/java/org/elasticsearch/index/IndexModule.java b/core/src/main/java/org/elasticsearch/index/IndexModule.java
index f23441fa908..f9eb3ec2b54 100644
--- a/core/src/main/java/org/elasticsearch/index/IndexModule.java
+++ b/core/src/main/java/org/elasticsearch/index/IndexModule.java
@@ -37,7 +37,7 @@ import org.elasticsearch.index.similarity.SimilarityProvider;
import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.index.store.IndexStore;
import org.elasticsearch.index.store.IndexStoreConfig;
-import org.elasticsearch.indices.cache.query.IndicesQueryCache;
+import org.elasticsearch.indices.IndicesQueryCache;
import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
import org.elasticsearch.indices.mapper.MapperRegistry;
diff --git a/core/src/main/java/org/elasticsearch/index/analysis/AnalysisRegistry.java b/core/src/main/java/org/elasticsearch/index/analysis/AnalysisRegistry.java
index 1fd3a4d96b0..a8a7b4fe004 100644
--- a/core/src/main/java/org/elasticsearch/index/analysis/AnalysisRegistry.java
+++ b/core/src/main/java/org/elasticsearch/index/analysis/AnalysisRegistry.java
@@ -57,7 +57,7 @@ public final class AnalysisRegistry implements Closeable {
private final Map cachedAnalyzer = new ConcurrentHashMap<>();
private final PrebuiltAnalysis prebuiltAnalysis;
private final HunspellService hunspellService;
- private final Environment environemnt;
+ private final Environment environment;
public AnalysisRegistry(HunspellService hunspellService, Environment environment) {
this(hunspellService, environment, Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap());
@@ -70,7 +70,7 @@ public final class AnalysisRegistry implements Closeable {
Map> analyzers) {
prebuiltAnalysis = new PrebuiltAnalysis();
this.hunspellService = hunspellService;
- this.environemnt = environment;
+ this.environment = environment;
final Map> charFilterBuilder = new HashMap<>(charFilters);
final Map> tokenFilterBuilder = new HashMap<>(tokenFilters);
final Map> tokenizerBuilder = new HashMap<>(tokenizers);
@@ -115,13 +115,13 @@ public final class AnalysisRegistry implements Closeable {
AnalysisModule.AnalysisProvider provider = analyzers.get(analyzer);
return provider == null ? null : cachedAnalyzer.computeIfAbsent(analyzer, (key) -> {
try {
- return provider.get(environemnt, key).get();
+ return provider.get(environment, key).get();
} catch (IOException ex) {
throw new ElasticsearchException("failed to load analyzer for name " + key, ex);
}}
);
}
- return analyzerProvider.get(environemnt, analyzer).get();
+ return analyzerProvider.get(environment, analyzer).get();
}
@Override
@@ -324,7 +324,7 @@ public final class AnalysisRegistry implements Closeable {
if (type == null) {
throw new IllegalArgumentException("Unknown " + toBuild + " type [" + typeName + "] for [" + name + "]");
}
- factory = type.get(settings, environemnt, name, currentSettings);
+ factory = type.get(settings, environment, name, currentSettings);
}
factories.put(name, factory);
} else {
@@ -335,7 +335,7 @@ public final class AnalysisRegistry implements Closeable {
if (type == null) {
throw new IllegalArgumentException("Unknown " + toBuild + " type [" + typeName + "] for [" + name + "]");
}
- final T factory = type.get(settings, environemnt, name, currentSettings);
+ final T factory = type.get(settings, environment, name, currentSettings);
factories.put(name, factory);
}
@@ -355,9 +355,9 @@ public final class AnalysisRegistry implements Closeable {
AnalysisModule.AnalysisProvider defaultProvider = defaultInstance.get(name);
final T instance;
if (defaultProvider == null) {
- instance = provider.get(settings, environemnt, name, defaultSettings);
+ instance = provider.get(settings, environment, name, defaultSettings);
} else {
- instance = defaultProvider.get(settings, environemnt, name, defaultSettings);
+ instance = defaultProvider.get(settings, environment, name, defaultSettings);
}
factories.put(name, instance);
String camelCase = Strings.toCamelCase(name);
@@ -371,7 +371,7 @@ public final class AnalysisRegistry implements Closeable {
final AnalysisModule.AnalysisProvider provider = entry.getValue();
final String camelCase = Strings.toCamelCase(name);
if (factories.containsKey(name) == false || (defaultInstance.containsKey(camelCase) == false && factories.containsKey(camelCase) == false)) {
- final T instance = provider.get(settings, environemnt, name, defaultSettings);
+ final T instance = provider.get(settings, environment, name, defaultSettings);
if (factories.containsKey(name) == false) {
factories.put(name, instance);
}
diff --git a/core/src/main/java/org/elasticsearch/index/cache/query/index/IndexQueryCache.java b/core/src/main/java/org/elasticsearch/index/cache/query/index/IndexQueryCache.java
index 352d6af5ee9..96b2ede2a99 100644
--- a/core/src/main/java/org/elasticsearch/index/cache/query/index/IndexQueryCache.java
+++ b/core/src/main/java/org/elasticsearch/index/cache/query/index/IndexQueryCache.java
@@ -25,7 +25,7 @@ import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.index.AbstractIndexComponent;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.cache.query.QueryCache;
-import org.elasticsearch.indices.cache.query.IndicesQueryCache;
+import org.elasticsearch.indices.IndicesQueryCache;
/**
* The index-level query cache. This class mostly delegates to the node-level
diff --git a/core/src/main/java/org/elasticsearch/index/cache/request/ShardRequestCache.java b/core/src/main/java/org/elasticsearch/index/cache/request/ShardRequestCache.java
index 5e9c8156046..ef81b288f92 100644
--- a/core/src/main/java/org/elasticsearch/index/cache/request/ShardRequestCache.java
+++ b/core/src/main/java/org/elasticsearch/index/cache/request/ShardRequestCache.java
@@ -19,27 +19,24 @@
package org.elasticsearch.index.cache.request;
+import org.apache.lucene.util.Accountable;
import org.elasticsearch.common.cache.RemovalListener;
import org.elasticsearch.common.cache.RemovalNotification;
import org.elasticsearch.common.metrics.CounterMetric;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.shard.AbstractIndexShardComponent;
import org.elasticsearch.index.shard.ShardId;
-import org.elasticsearch.indices.cache.request.IndicesRequestCache;
+import org.elasticsearch.indices.IndicesRequestCache;
/**
*/
-public class ShardRequestCache extends AbstractIndexShardComponent implements RemovalListener {
+public final class ShardRequestCache {
final CounterMetric evictionsMetric = new CounterMetric();
final CounterMetric totalMetric = new CounterMetric();
final CounterMetric hitCount = new CounterMetric();
final CounterMetric missCount = new CounterMetric();
- public ShardRequestCache(ShardId shardId, IndexSettings indexSettings) {
- super(shardId, indexSettings);
- }
-
public RequestCacheStats stats() {
return new RequestCacheStats(totalMetric.count(), evictionsMetric.count(), hitCount.count(), missCount.count());
}
@@ -52,21 +49,20 @@ public class ShardRequestCache extends AbstractIndexShardComponent implements Re
missCount.inc();
}
- public void onCached(IndicesRequestCache.Key key, IndicesRequestCache.Value value) {
+ public void onCached(Accountable key, Accountable value) {
totalMetric.inc(key.ramBytesUsed() + value.ramBytesUsed());
}
- @Override
- public void onRemoval(RemovalNotification removalNotification) {
- if (removalNotification.getRemovalReason() == RemovalNotification.RemovalReason.EVICTED) {
+ public void onRemoval(Accountable key, Accountable value, boolean evicted) {
+ if (evicted) {
evictionsMetric.inc();
}
long dec = 0;
- if (removalNotification.getKey() != null) {
- dec += removalNotification.getKey().ramBytesUsed();
+ if (key != null) {
+ dec += key.ramBytesUsed();
}
- if (removalNotification.getValue() != null) {
- dec += removalNotification.getValue().ramBytesUsed();
+ if (value != null) {
+ dec += value.ramBytesUsed();
}
totalMetric.dec(dec);
}
diff --git a/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java b/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java
index f02f924bc39..78bdcb0f7f3 100644
--- a/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java
+++ b/core/src/main/java/org/elasticsearch/index/fielddata/IndexFieldDataService.java
@@ -36,6 +36,7 @@ import org.elasticsearch.index.fielddata.plain.ParentChildIndexFieldData;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.core.BooleanFieldMapper;
+import org.elasticsearch.index.mapper.core.KeywordFieldMapper;
import org.elasticsearch.index.mapper.internal.IndexFieldMapper;
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
import org.elasticsearch.index.shard.ShardId;
@@ -94,6 +95,7 @@ public class IndexFieldDataService extends AbstractIndexComponent implements Clo
static {
Map buildersByTypeBuilder = new HashMap<>();
buildersByTypeBuilder.put("string", new PagedBytesIndexFieldData.Builder());
+ buildersByTypeBuilder.put(KeywordFieldMapper.CONTENT_TYPE, MISSING_DOC_VALUES_BUILDER);
buildersByTypeBuilder.put("float", MISSING_DOC_VALUES_BUILDER);
buildersByTypeBuilder.put("double", MISSING_DOC_VALUES_BUILDER);
buildersByTypeBuilder.put("byte", MISSING_DOC_VALUES_BUILDER);
@@ -110,6 +112,7 @@ public class IndexFieldDataService extends AbstractIndexComponent implements Clo
docValuesBuildersByType = MapBuilder.newMapBuilder()
.put("string", new DocValuesIndexFieldData.Builder())
+ .put(KeywordFieldMapper.CONTENT_TYPE, new DocValuesIndexFieldData.Builder())
.put("float", new DocValuesIndexFieldData.Builder().numericType(IndexNumericFieldData.NumericType.FLOAT))
.put("double", new DocValuesIndexFieldData.Builder().numericType(IndexNumericFieldData.NumericType.DOUBLE))
.put("byte", new DocValuesIndexFieldData.Builder().numericType(IndexNumericFieldData.NumericType.BYTE))
@@ -126,6 +129,9 @@ public class IndexFieldDataService extends AbstractIndexComponent implements Clo
.put(Tuple.tuple("string", DOC_VALUES_FORMAT), new DocValuesIndexFieldData.Builder())
.put(Tuple.tuple("string", DISABLED_FORMAT), DISABLED_BUILDER)
+ .put(Tuple.tuple(KeywordFieldMapper.CONTENT_TYPE, DOC_VALUES_FORMAT), new DocValuesIndexFieldData.Builder())
+ .put(Tuple.tuple(KeywordFieldMapper.CONTENT_TYPE, DISABLED_FORMAT), DISABLED_BUILDER)
+
.put(Tuple.tuple("float", DOC_VALUES_FORMAT), new DocValuesIndexFieldData.Builder().numericType(IndexNumericFieldData.NumericType.FLOAT))
.put(Tuple.tuple("float", DISABLED_FORMAT), DISABLED_BUILDER)
diff --git a/core/src/main/java/org/elasticsearch/index/fielddata/plain/AbstractIndexGeoPointFieldData.java b/core/src/main/java/org/elasticsearch/index/fielddata/plain/AbstractIndexGeoPointFieldData.java
index a8114c41f9b..e9dae4970a9 100644
--- a/core/src/main/java/org/elasticsearch/index/fielddata/plain/AbstractIndexGeoPointFieldData.java
+++ b/core/src/main/java/org/elasticsearch/index/fielddata/plain/AbstractIndexGeoPointFieldData.java
@@ -19,10 +19,12 @@
package org.elasticsearch.index.fielddata.plain;
+import org.apache.lucene.spatial.geopoint.document.GeoPointField;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefIterator;
import org.apache.lucene.util.CharsRefBuilder;
import org.apache.lucene.util.NumericUtils;
+import org.elasticsearch.Version;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.index.IndexSettings;
@@ -45,7 +47,7 @@ abstract class AbstractIndexGeoPointFieldData extends AbstractIndexFieldData build(IndexSettings indexSettings, MappedFieldType fieldType, IndexFieldDataCache cache,
CircuitBreakerService breakerService, MapperService mapperService) {
return new GeoPointArrayIndexFieldData(indexSettings, fieldType.name(), fieldType.fieldDataType(), cache,
- breakerService, fieldType.fieldDataType().getSettings()
- .getAsVersion(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT).before(Version.V_2_2_0) ||
- indexSettings.getIndexVersionCreated().before(Version.V_2_2_0));
+ breakerService);
}
}
public GeoPointArrayIndexFieldData(IndexSettings indexSettings, String fieldName,
- FieldDataType fieldDataType, IndexFieldDataCache cache, CircuitBreakerService breakerService,
- final boolean indexCreatedBefore22) {
+ FieldDataType fieldDataType, IndexFieldDataCache cache, CircuitBreakerService breakerService) {
super(indexSettings, fieldName, fieldDataType, cache);
this.breakerService = breakerService;
- this.indexCreatedBefore22 = indexCreatedBefore22;
}
@Override
@@ -82,7 +78,8 @@ public class GeoPointArrayIndexFieldData extends AbstractIndexGeoPointFieldData
estimator.afterLoad(null, data.ramBytesUsed());
return data;
}
- return (indexCreatedBefore22 == true) ? loadLegacyFieldData(reader, estimator, terms, data) : loadFieldData22(reader, estimator, terms, data);
+ return (indexSettings.getIndexVersionCreated().before(Version.V_2_2_0) == true) ?
+ loadLegacyFieldData(reader, estimator, terms, data) : loadFieldData22(reader, estimator, terms, data);
}
/**
@@ -95,7 +92,9 @@ public class GeoPointArrayIndexFieldData extends AbstractIndexGeoPointFieldData
OrdinalsBuilder.DEFAULT_ACCEPTABLE_OVERHEAD_RATIO);
boolean success = false;
try (OrdinalsBuilder builder = new OrdinalsBuilder(reader.maxDoc(), acceptableTransientOverheadRatio)) {
- final GeoPointTermsEnum iter = new GeoPointTermsEnum(builder.buildFromTerms(OrdinalsBuilder.wrapNumeric64Bit(terms.iterator())));
+ final GeoPointField.TermEncoding termEncoding = indexSettings.getIndexVersionCreated().onOrAfter(Version.V_2_3_0) ?
+ GeoPointField.TermEncoding.PREFIX : GeoPointField.TermEncoding.NUMERIC;
+ final GeoPointTermsEnum iter = new GeoPointTermsEnum(builder.buildFromTerms(OrdinalsBuilder.wrapNumeric64Bit(terms.iterator())), termEncoding);
Long hashedPoint;
long numTerms = 0;
while ((hashedPoint = iter.next()) != null) {
@@ -181,4 +180,4 @@ public class GeoPointArrayIndexFieldData extends AbstractIndexGeoPointFieldData
}
}
}
-}
\ No newline at end of file
+}
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java b/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java
index 20aeb34bd39..b1f6f7cd9bd 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapperParser.java
@@ -43,7 +43,6 @@ import java.util.Map;
import java.util.function.Supplier;
import static java.util.Collections.unmodifiableMap;
-import static org.elasticsearch.index.mapper.MapperBuilders.doc;
public class DocumentMapperParser {
@@ -111,7 +110,7 @@ public class DocumentMapperParser {
Mapper.TypeParser.ParserContext parserContext = parserContext(type);
// parse RootObjectMapper
- DocumentMapper.Builder docBuilder = doc((RootObjectMapper.Builder) rootObjectTypeParser.parse(type, mapping, parserContext), mapperService);
+ DocumentMapper.Builder docBuilder = new DocumentMapper.Builder((RootObjectMapper.Builder) rootObjectTypeParser.parse(type, mapping, parserContext), mapperService);
Iterator> iterator = mapping.entrySet().iterator();
// parse DocumentMapper
while(iterator.hasNext()) {
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java b/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java
index c1362287d67..ac7240495bd 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java
@@ -28,7 +28,15 @@ import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.IndexSettings;
+import org.elasticsearch.index.mapper.core.BinaryFieldMapper;
+import org.elasticsearch.index.mapper.core.BooleanFieldMapper;
+import org.elasticsearch.index.mapper.core.DateFieldMapper;
import org.elasticsearch.index.mapper.core.DateFieldMapper.DateFieldType;
+import org.elasticsearch.index.mapper.core.DoubleFieldMapper;
+import org.elasticsearch.index.mapper.core.FloatFieldMapper;
+import org.elasticsearch.index.mapper.core.IntegerFieldMapper;
+import org.elasticsearch.index.mapper.core.LongFieldMapper;
+import org.elasticsearch.index.mapper.core.StringFieldMapper;
import org.elasticsearch.index.mapper.core.StringFieldMapper.StringFieldType;
import org.elasticsearch.index.mapper.internal.TypeFieldMapper;
import org.elasticsearch.index.mapper.internal.UidFieldMapper;
@@ -323,7 +331,7 @@ class DocumentParser implements Closeable {
context.path().remove();
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "object");
if (builder == null) {
- builder = MapperBuilders.object(currentFieldName).enabled(true);
+ builder = new ObjectMapper.Builder(currentFieldName).enabled(true);
// if this is a non root object, then explicitly set the dynamic behavior if set
if (!(mapper instanceof RootObjectMapper) && mapper.dynamic() != ObjectMapper.Defaults.DYNAMIC) {
((ObjectMapper.Builder) builder).dynamic(mapper.dynamic());
@@ -442,37 +450,37 @@ class DocumentParser implements Closeable {
if (fieldType instanceof StringFieldType) {
builder = context.root().findTemplateBuilder(context, currentFieldName, "string");
if (builder == null) {
- builder = MapperBuilders.stringField(currentFieldName);
+ builder = new StringFieldMapper.Builder(currentFieldName);
}
} else if (fieldType instanceof DateFieldType) {
builder = context.root().findTemplateBuilder(context, currentFieldName, "date");
if (builder == null) {
- builder = MapperBuilders.dateField(currentFieldName);
+ builder = new DateFieldMapper.Builder(currentFieldName);
}
} else if (fieldType.numericType() != null) {
switch (fieldType.numericType()) {
case LONG:
builder = context.root().findTemplateBuilder(context, currentFieldName, "long");
if (builder == null) {
- builder = MapperBuilders.longField(currentFieldName);
+ builder = new LongFieldMapper.Builder(currentFieldName);
}
break;
case DOUBLE:
builder = context.root().findTemplateBuilder(context, currentFieldName, "double");
if (builder == null) {
- builder = MapperBuilders.doubleField(currentFieldName);
+ builder = new DoubleFieldMapper.Builder(currentFieldName);
}
break;
case INT:
builder = context.root().findTemplateBuilder(context, currentFieldName, "integer");
if (builder == null) {
- builder = MapperBuilders.integerField(currentFieldName);
+ builder = new IntegerFieldMapper.Builder(currentFieldName);
}
break;
case FLOAT:
builder = context.root().findTemplateBuilder(context, currentFieldName, "float");
if (builder == null) {
- builder = MapperBuilders.floatField(currentFieldName);
+ builder = new FloatFieldMapper.Builder(currentFieldName);
}
break;
default:
@@ -503,7 +511,7 @@ class DocumentParser implements Closeable {
dateTimeFormatter.parser().parseMillis(text);
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "date");
if (builder == null) {
- builder = MapperBuilders.dateField(currentFieldName).dateTimeFormatter(dateTimeFormatter);
+ builder = new DateFieldMapper.Builder(currentFieldName).dateTimeFormatter(dateTimeFormatter);
}
return builder;
} catch (Exception e) {
@@ -518,7 +526,7 @@ class DocumentParser implements Closeable {
Long.parseLong(text);
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "long");
if (builder == null) {
- builder = MapperBuilders.longField(currentFieldName);
+ builder = new LongFieldMapper.Builder(currentFieldName);
}
return builder;
} catch (NumberFormatException e) {
@@ -528,7 +536,7 @@ class DocumentParser implements Closeable {
Double.parseDouble(text);
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "double");
if (builder == null) {
- builder = MapperBuilders.doubleField(currentFieldName);
+ builder = new DoubleFieldMapper.Builder(currentFieldName);
}
return builder;
} catch (NumberFormatException e) {
@@ -537,7 +545,7 @@ class DocumentParser implements Closeable {
}
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "string");
if (builder == null) {
- builder = MapperBuilders.stringField(currentFieldName);
+ builder = new StringFieldMapper.Builder(currentFieldName);
}
return builder;
} else if (token == XContentParser.Token.VALUE_NUMBER) {
@@ -545,7 +553,7 @@ class DocumentParser implements Closeable {
if (numberType == XContentParser.NumberType.INT || numberType == XContentParser.NumberType.LONG) {
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "long");
if (builder == null) {
- builder = MapperBuilders.longField(currentFieldName);
+ builder = new LongFieldMapper.Builder(currentFieldName);
}
return builder;
} else if (numberType == XContentParser.NumberType.FLOAT || numberType == XContentParser.NumberType.DOUBLE) {
@@ -554,20 +562,20 @@ class DocumentParser implements Closeable {
// no templates are defined, we use float by default instead of double
// since this is much more space-efficient and should be enough most of
// the time
- builder = MapperBuilders.floatField(currentFieldName);
+ builder = new FloatFieldMapper.Builder(currentFieldName);
}
return builder;
}
} else if (token == XContentParser.Token.VALUE_BOOLEAN) {
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "boolean");
if (builder == null) {
- builder = MapperBuilders.booleanField(currentFieldName);
+ builder = new BooleanFieldMapper.Builder(currentFieldName);
}
return builder;
} else if (token == XContentParser.Token.VALUE_EMBEDDED_OBJECT) {
Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "binary");
if (builder == null) {
- builder = MapperBuilders.binaryField(currentFieldName);
+ builder = new BinaryFieldMapper.Builder(currentFieldName);
}
return builder;
} else {
@@ -677,7 +685,7 @@ class DocumentParser implements Closeable {
if (!(parent instanceof RootObjectMapper) && parent.dynamic() != ObjectMapper.Defaults.DYNAMIC) {
((ObjectMapper.Builder) builder).dynamic(parent.dynamic());
}
- builder = MapperBuilders.object(paths[i]).enabled(true);
+ builder = new ObjectMapper.Builder(paths[i]).enabled(true);
}
Mapper.BuilderContext builderContext = new Mapper.BuilderContext(context.indexSettings(), context.path());
mapper = (ObjectMapper) builder.build(builderContext);
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/MapperBuilders.java b/core/src/main/java/org/elasticsearch/index/mapper/MapperBuilders.java
deleted file mode 100644
index 9ea9e99f01b..00000000000
--- a/core/src/main/java/org/elasticsearch/index/mapper/MapperBuilders.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 org.elasticsearch.index.mapper.core.BinaryFieldMapper;
-import org.elasticsearch.index.mapper.core.BooleanFieldMapper;
-import org.elasticsearch.index.mapper.core.ByteFieldMapper;
-import org.elasticsearch.index.mapper.core.CompletionFieldMapper;
-import org.elasticsearch.index.mapper.core.DateFieldMapper;
-import org.elasticsearch.index.mapper.core.DoubleFieldMapper;
-import org.elasticsearch.index.mapper.core.FloatFieldMapper;
-import org.elasticsearch.index.mapper.core.IntegerFieldMapper;
-import org.elasticsearch.index.mapper.core.LongFieldMapper;
-import org.elasticsearch.index.mapper.core.ShortFieldMapper;
-import org.elasticsearch.index.mapper.core.StringFieldMapper;
-import org.elasticsearch.index.mapper.core.TokenCountFieldMapper;
-import org.elasticsearch.index.mapper.geo.GeoShapeFieldMapper;
-import org.elasticsearch.index.mapper.ip.IpFieldMapper;
-import org.elasticsearch.index.mapper.object.ObjectMapper;
-import org.elasticsearch.index.mapper.object.RootObjectMapper;
-
-public final class MapperBuilders {
-
- private MapperBuilders() {}
-
- public static DocumentMapper.Builder doc(RootObjectMapper.Builder objectBuilder, MapperService mapperService) {
- return new DocumentMapper.Builder(objectBuilder, mapperService);
- }
-
- public static RootObjectMapper.Builder rootObject(String name) {
- return new RootObjectMapper.Builder(name);
- }
-
- public static ObjectMapper.Builder object(String name) {
- return new ObjectMapper.Builder(name);
- }
-
- public static BooleanFieldMapper.Builder booleanField(String name) {
- return new BooleanFieldMapper.Builder(name);
- }
-
- public static StringFieldMapper.Builder stringField(String name) {
- return new StringFieldMapper.Builder(name);
- }
-
- public static BinaryFieldMapper.Builder binaryField(String name) {
- return new BinaryFieldMapper.Builder(name);
- }
-
- public static DateFieldMapper.Builder dateField(String name) {
- return new DateFieldMapper.Builder(name);
- }
-
- public static IpFieldMapper.Builder ipField(String name) {
- return new IpFieldMapper.Builder(name);
- }
-
- public static ShortFieldMapper.Builder shortField(String name) {
- return new ShortFieldMapper.Builder(name);
- }
-
- public static ByteFieldMapper.Builder byteField(String name) {
- return new ByteFieldMapper.Builder(name);
- }
-
- public static IntegerFieldMapper.Builder integerField(String name) {
- return new IntegerFieldMapper.Builder(name);
- }
-
- public static TokenCountFieldMapper.Builder tokenCountField(String name) {
- return new TokenCountFieldMapper.Builder(name);
- }
-
- public static LongFieldMapper.Builder longField(String name) {
- return new LongFieldMapper.Builder(name);
- }
-
- public static FloatFieldMapper.Builder floatField(String name) {
- return new FloatFieldMapper.Builder(name);
- }
-
- public static DoubleFieldMapper.Builder doubleField(String name) {
- return new DoubleFieldMapper.Builder(name);
- }
-
- public static GeoShapeFieldMapper.Builder geoShapeField(String name) {
- return new GeoShapeFieldMapper.Builder(name);
- }
-
- public static CompletionFieldMapper.Builder completionField(String name) {
- return new CompletionFieldMapper.Builder(name);
- }
-}
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/BinaryFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/BinaryFieldMapper.java
index f71267fa75b..9fc12a3dd0c 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/BinaryFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/BinaryFieldMapper.java
@@ -42,7 +42,6 @@ import java.io.IOException;
import java.util.List;
import java.util.Map;
-import static org.elasticsearch.index.mapper.MapperBuilders.binaryField;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseField;
/**
@@ -79,7 +78,7 @@ public class BinaryFieldMapper extends FieldMapper {
public static class TypeParser implements Mapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException {
- BinaryFieldMapper.Builder builder = binaryField(name);
+ BinaryFieldMapper.Builder builder = new BinaryFieldMapper.Builder(name);
parseField(builder, name, node, parserContext);
return builder;
}
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java
index 29d2ce2176f..4b49d644d5f 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java
@@ -41,7 +41,6 @@ import java.util.List;
import java.util.Map;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.lenientNodeBooleanValue;
-import static org.elasticsearch.index.mapper.MapperBuilders.booleanField;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseField;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseMultiField;
@@ -96,7 +95,7 @@ public class BooleanFieldMapper extends FieldMapper {
public static class TypeParser implements Mapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException {
- BooleanFieldMapper.Builder builder = booleanField(name);
+ BooleanFieldMapper.Builder builder = new BooleanFieldMapper.Builder(name);
parseField(builder, name, node, parserContext);
for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = iterator.next();
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java
index b1553d455d7..91019f0aa3f 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java
@@ -49,7 +49,6 @@ import java.util.List;
import java.util.Map;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeByteValue;
-import static org.elasticsearch.index.mapper.MapperBuilders.byteField;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
/**
@@ -97,7 +96,7 @@ public class ByteFieldMapper extends NumberFieldMapper {
public static class TypeParser implements Mapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException {
- ByteFieldMapper.Builder builder = byteField(name);
+ ByteFieldMapper.Builder builder = new ByteFieldMapper.Builder(name);
parseNumberField(builder, name, node, parserContext);
for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = iterator.next();
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/CompletionFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/CompletionFieldMapper.java
index 1e45780cf18..057a8957121 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/CompletionFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/CompletionFieldMapper.java
@@ -58,7 +58,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import static org.elasticsearch.index.mapper.MapperBuilders.completionField;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseMultiField;
/**
@@ -119,7 +118,7 @@ public class CompletionFieldMapper extends FieldMapper implements ArrayValueMapp
@Override
public Mapper.Builder, ?> parse(String name, Map node, ParserContext parserContext) throws MapperParsingException {
- CompletionFieldMapper.Builder builder = completionField(name);
+ CompletionFieldMapper.Builder builder = new CompletionFieldMapper.Builder(name);
NamedAnalyzer indexAnalyzer = null;
NamedAnalyzer searchAnalyzer = null;
for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) {
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java
index 4b752b2b2af..5a355e2f3d4 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java
@@ -63,7 +63,6 @@ import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
-import static org.elasticsearch.index.mapper.MapperBuilders.dateField;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseDateTimeFormatter;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
@@ -153,7 +152,7 @@ public class DateFieldMapper extends NumberFieldMapper {
public static class TypeParser implements Mapper.TypeParser {
@Override
public Mapper.Builder, ?> parse(String name, Map node, ParserContext parserContext) throws MapperParsingException {
- DateFieldMapper.Builder builder = dateField(name);
+ DateFieldMapper.Builder builder = new DateFieldMapper.Builder(name);
parseNumberField(builder, name, node, parserContext);
boolean configuredFormat = false;
for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) {
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java
index 6c3f24d479e..50ce90aa6c3 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java
@@ -51,7 +51,6 @@ 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.index.mapper.MapperBuilders.doubleField;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
/**
@@ -98,7 +97,7 @@ public class DoubleFieldMapper extends NumberFieldMapper {
public static class TypeParser implements Mapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException {
- DoubleFieldMapper.Builder builder = doubleField(name);
+ DoubleFieldMapper.Builder builder = new DoubleFieldMapper.Builder(name);
parseNumberField(builder, name, node, parserContext);
for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = iterator.next();
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java
index 31c22d626ee..c30e307758c 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java
@@ -52,7 +52,6 @@ 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.index.mapper.MapperBuilders.floatField;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
/**
@@ -99,7 +98,7 @@ public class FloatFieldMapper extends NumberFieldMapper {
public static class TypeParser implements Mapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException {
- FloatFieldMapper.Builder builder = floatField(name);
+ FloatFieldMapper.Builder builder = new FloatFieldMapper.Builder(name);
parseNumberField(builder, name, node, parserContext);
for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = iterator.next();
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java
index 27315ad042a..e37b715278f 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java
@@ -51,7 +51,6 @@ import java.util.List;
import java.util.Map;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeIntegerValue;
-import static org.elasticsearch.index.mapper.MapperBuilders.integerField;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
/**
@@ -104,7 +103,7 @@ public class IntegerFieldMapper extends NumberFieldMapper {
public static class TypeParser implements Mapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException {
- IntegerFieldMapper.Builder builder = integerField(name);
+ IntegerFieldMapper.Builder builder = new IntegerFieldMapper.Builder(name);
parseNumberField(builder, name, node, parserContext);
for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = iterator.next();
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/KeywordFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/KeywordFieldMapper.java
new file mode 100644
index 00000000000..35f1ee7ad58
--- /dev/null
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/KeywordFieldMapper.java
@@ -0,0 +1,274 @@
+/*
+ * 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.core;
+
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.SortedSetDocValuesField;
+import org.apache.lucene.index.IndexOptions;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.util.BytesRef;
+import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentParser;
+import org.elasticsearch.common.xcontent.support.XContentMapValues;
+import org.elasticsearch.index.mapper.FieldMapper;
+import org.elasticsearch.index.mapper.MappedFieldType;
+import org.elasticsearch.index.mapper.Mapper;
+import org.elasticsearch.index.mapper.MapperParsingException;
+import org.elasticsearch.index.mapper.ParseContext;
+import org.elasticsearch.index.mapper.internal.AllFieldMapper;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import static org.elasticsearch.index.mapper.core.TypeParsers.parseField;
+import static org.elasticsearch.index.mapper.core.TypeParsers.parseMultiField;
+
+/**
+ * A field mapper for keywords. This mapper accepts strings and indexes them as-is.
+ */
+public final class KeywordFieldMapper extends FieldMapper implements AllFieldMapper.IncludeInAll {
+
+ public static final String CONTENT_TYPE = "keyword";
+
+ public static class Defaults {
+ public static final MappedFieldType FIELD_TYPE = new KeywordFieldType();
+
+ static {
+ FIELD_TYPE.setTokenized(false);
+ FIELD_TYPE.setOmitNorms(true);
+ FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
+ FIELD_TYPE.freeze();
+ }
+
+ public static final String NULL_VALUE = null;
+ public static final int IGNORE_ABOVE = Integer.MAX_VALUE;
+ }
+
+ public static class Builder extends FieldMapper.Builder {
+
+ protected String nullValue = Defaults.NULL_VALUE;
+ protected int ignoreAbove = Defaults.IGNORE_ABOVE;
+
+ public Builder(String name) {
+ super(name, Defaults.FIELD_TYPE, Defaults.FIELD_TYPE);
+ builder = this;
+ }
+
+ public Builder ignoreAbove(int ignoreAbove) {
+ if (ignoreAbove < 0) {
+ throw new IllegalArgumentException("[ignore_above] must be positive, got " + ignoreAbove);
+ }
+ this.ignoreAbove = ignoreAbove;
+ return this;
+ }
+
+ @Override
+ public Builder indexOptions(IndexOptions indexOptions) {
+ if (fieldType.indexOptions().compareTo(IndexOptions.DOCS_AND_FREQS) > 0) {
+ throw new IllegalArgumentException("The [keyword] field does not support positions, got [index_options]="
+ + indexOptionToString(fieldType.indexOptions()));
+ }
+ return super.indexOptions(indexOptions);
+ }
+
+ @Override
+ public KeywordFieldMapper build(BuilderContext context) {
+ setupFieldType(context);
+ KeywordFieldMapper fieldMapper = new KeywordFieldMapper(
+ name, fieldType, defaultFieldType, ignoreAbove,
+ context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
+ return fieldMapper.includeInAll(includeInAll);
+ }
+ }
+
+ public static class TypeParser implements Mapper.TypeParser {
+ @Override
+ public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException {
+ KeywordFieldMapper.Builder builder = new KeywordFieldMapper.Builder(name);
+ parseField(builder, name, node, parserContext);
+ for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) {
+ Map.Entry entry = iterator.next();
+ String propName = Strings.toUnderscoreCase(entry.getKey());
+ Object propNode = entry.getValue();
+ if (propName.equals("null_value")) {
+ if (propNode == null) {
+ throw new MapperParsingException("Property [null_value] cannot be null.");
+ }
+ builder.nullValue(propNode.toString());
+ iterator.remove();
+ } else if (propName.equals("ignore_above")) {
+ builder.ignoreAbove(XContentMapValues.nodeIntegerValue(propNode, -1));
+ iterator.remove();
+ } else if (parseMultiField(builder, name, parserContext, propName, propNode)) {
+ iterator.remove();
+ }
+ }
+ return builder;
+ }
+ }
+
+ public static final class KeywordFieldType extends MappedFieldType {
+
+ public KeywordFieldType() {}
+
+ protected KeywordFieldType(KeywordFieldType ref) {
+ super(ref);
+ }
+
+ public KeywordFieldType clone() {
+ return new KeywordFieldType(this);
+ }
+
+ @Override
+ public String typeName() {
+ return CONTENT_TYPE;
+ }
+
+ @Override
+ public String value(Object value) {
+ if (value == null) {
+ return null;
+ }
+ return value.toString();
+ }
+
+ @Override
+ public Query nullValueQuery() {
+ if (nullValue() == null) {
+ return null;
+ }
+ return termQuery(nullValue(), null);
+ }
+ }
+
+ private Boolean includeInAll;
+ private int ignoreAbove;
+
+ protected KeywordFieldMapper(String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType,
+ int ignoreAbove, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) {
+ super(simpleName, fieldType, defaultFieldType, indexSettings, multiFields, copyTo);
+ assert fieldType.indexOptions().compareTo(IndexOptions.DOCS_AND_FREQS) <= 0;
+ this.ignoreAbove = ignoreAbove;
+ }
+
+ @Override
+ protected KeywordFieldMapper clone() {
+ return (KeywordFieldMapper) super.clone();
+ }
+
+ @Override
+ public KeywordFieldMapper includeInAll(Boolean includeInAll) {
+ if (includeInAll != null) {
+ KeywordFieldMapper clone = clone();
+ clone.includeInAll = includeInAll;
+ return clone;
+ } else {
+ return this;
+ }
+ }
+
+ @Override
+ public KeywordFieldMapper includeInAllIfNotSet(Boolean includeInAll) {
+ if (includeInAll != null && this.includeInAll == null) {
+ KeywordFieldMapper clone = clone();
+ clone.includeInAll = includeInAll;
+ return clone;
+ } else {
+ return this;
+ }
+ }
+
+ @Override
+ public KeywordFieldMapper unsetIncludeInAll() {
+ if (includeInAll != null) {
+ KeywordFieldMapper clone = clone();
+ clone.includeInAll = null;
+ return clone;
+ } else {
+ return this;
+ }
+ }
+
+ @Override
+ protected void parseCreateField(ParseContext context, List fields) throws IOException {
+ final String value;
+ if (context.externalValueSet()) {
+ value = context.externalValue().toString();
+ } else {
+ XContentParser parser = context.parser();
+ if (parser.currentToken() == XContentParser.Token.VALUE_NULL) {
+ value = fieldType().nullValueAsString();
+ } else {
+ value = parser.textOrNull();
+ }
+ }
+
+ if (value == null || value.length() > ignoreAbove) {
+ return;
+ }
+
+ if (context.includeInAll(includeInAll, this)) {
+ context.allEntries().addText(fieldType().name(), value, fieldType().boost());
+ }
+
+ if (fieldType().indexOptions() != IndexOptions.NONE || fieldType().stored()) {
+ Field field = new Field(fieldType().name(), value, fieldType());
+ fields.add(field);
+ }
+ if (fieldType().hasDocValues()) {
+ fields.add(new SortedSetDocValuesField(fieldType().name(), new BytesRef(value)));
+ }
+ }
+
+ @Override
+ protected String contentType() {
+ return CONTENT_TYPE;
+ }
+
+ @Override
+ protected void doMerge(Mapper mergeWith, boolean updateAllTypes) {
+ super.doMerge(mergeWith, updateAllTypes);
+ this.includeInAll = ((KeywordFieldMapper) mergeWith).includeInAll;
+ this.ignoreAbove = ((KeywordFieldMapper) mergeWith).ignoreAbove;
+ }
+
+ @Override
+ protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
+ super.doXContentBody(builder, includeDefaults, params);
+
+ if (includeDefaults || fieldType().nullValue() != null) {
+ builder.field("null_value", fieldType().nullValue());
+ }
+
+ if (includeInAll != null) {
+ builder.field("include_in_all", includeInAll);
+ } else if (includeDefaults) {
+ builder.field("include_in_all", true);
+ }
+
+ if (includeDefaults || ignoreAbove != Defaults.IGNORE_ABOVE) {
+ builder.field("ignore_above", ignoreAbove);
+ }
+ }
+}
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java
index 984dc3fed53..51375a6903d 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java
@@ -51,7 +51,6 @@ import java.util.List;
import java.util.Map;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeLongValue;
-import static org.elasticsearch.index.mapper.MapperBuilders.longField;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
/**
@@ -103,7 +102,7 @@ public class LongFieldMapper extends NumberFieldMapper {
public static class TypeParser implements Mapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException {
- LongFieldMapper.Builder builder = longField(name);
+ LongFieldMapper.Builder builder = new LongFieldMapper.Builder(name);
parseNumberField(builder, name, node, parserContext);
for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = iterator.next();
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java
index 01bd16d2c1e..2eead1a124b 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java
@@ -51,7 +51,6 @@ import java.util.List;
import java.util.Map;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeShortValue;
-import static org.elasticsearch.index.mapper.MapperBuilders.shortField;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
/**
@@ -101,7 +100,7 @@ public class ShortFieldMapper extends NumberFieldMapper {
public static class TypeParser implements Mapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException {
- ShortFieldMapper.Builder builder = shortField(name);
+ ShortFieldMapper.Builder builder = new ShortFieldMapper.Builder(name);
parseNumberField(builder, name, node, parserContext);
for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = iterator.next();
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java
index 52739e0b6f8..6812fa520aa 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java
@@ -45,7 +45,6 @@ import java.util.List;
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.core.TypeParsers.parseMultiField;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseTextField;
@@ -146,7 +145,7 @@ public class StringFieldMapper extends FieldMapper implements AllFieldMapper.Inc
public static class TypeParser implements Mapper.TypeParser {
@Override
public Mapper.Builder parse(String fieldName, Map node, ParserContext parserContext) throws MapperParsingException {
- StringFieldMapper.Builder builder = stringField(fieldName);
+ StringFieldMapper.Builder builder = new StringFieldMapper.Builder(fieldName);
// hack for the fact that string can't just accept true/false for
// the index property and still accepts no/not_analyzed/analyzed
final Object index = node.remove("index");
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapper.java
index 85df5ea3d3b..4e850176199 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapper.java
@@ -43,7 +43,6 @@ 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.index.mapper.MapperBuilders.tokenCountField;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
/**
@@ -98,7 +97,7 @@ public class TokenCountFieldMapper extends IntegerFieldMapper {
@Override
@SuppressWarnings("unchecked")
public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException {
- TokenCountFieldMapper.Builder builder = tokenCountField(name);
+ TokenCountFieldMapper.Builder builder = new TokenCountFieldMapper.Builder(name);
for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = iterator.next();
String propName = Strings.toUnderscoreCase(entry.getKey());
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/geo/BaseGeoPointFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/geo/BaseGeoPointFieldMapper.java
index 0a992aeb27a..69d5f60f114 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/geo/BaseGeoPointFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/geo/BaseGeoPointFieldMapper.java
@@ -21,7 +21,8 @@ package org.elasticsearch.index.mapper.geo;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexOptions;
-import org.apache.lucene.util.GeoHashUtils;
+import org.apache.lucene.spatial.geopoint.document.GeoPointField;
+import org.apache.lucene.spatial.util.GeoHashUtils;
import org.apache.lucene.util.NumericUtils;
import org.elasticsearch.Version;
import org.elasticsearch.common.Explicit;
@@ -29,7 +30,6 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.Iterators;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.GeoUtils;
-import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
@@ -42,6 +42,7 @@ import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.core.DoubleFieldMapper;
import org.elasticsearch.index.mapper.core.NumberFieldMapper;
import org.elasticsearch.index.mapper.core.StringFieldMapper;
+import org.elasticsearch.index.mapper.core.TokenCountFieldMapper;
import org.elasticsearch.index.mapper.object.ArrayValueMapperParser;
import java.io.IOException;
@@ -50,8 +51,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import static org.elasticsearch.index.mapper.MapperBuilders.doubleField;
-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.parseMultiField;
@@ -159,8 +158,8 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr
context.path().add(name);
if (enableLatLon) {
- NumberFieldMapper.Builder, ?> latMapperBuilder = doubleField(Names.LAT).includeInAll(false);
- NumberFieldMapper.Builder, ?> lonMapperBuilder = doubleField(Names.LON).includeInAll(false);
+ NumberFieldMapper.Builder, ?> latMapperBuilder = new DoubleFieldMapper.Builder(Names.LAT).includeInAll(false);
+ NumberFieldMapper.Builder, ?> lonMapperBuilder = new DoubleFieldMapper.Builder(Names.LON).includeInAll(false);
if (precisionStep != null) {
latMapperBuilder.precisionStep(precisionStep);
lonMapperBuilder.precisionStep(precisionStep);
@@ -172,7 +171,7 @@ public abstract class BaseGeoPointFieldMapper extends FieldMapper implements Arr
StringFieldMapper geoHashMapper = null;
if (enableGeoHash || enableGeoHashPrefix) {
// TODO: possible also implicitly enable geohash if geohash precision is set
- geoHashMapper = stringField(Names.GEOHASH).index(true).tokenized(false).includeInAll(false).store(fieldType.stored())
+ geoHashMapper = new StringFieldMapper.Builder(Names.GEOHASH).index(true).tokenized(false).includeInAll(false).store(fieldType.stored())
.omitNorms(true).indexOptions(IndexOptions.DOCS).build(context);
geoPointFieldType.setGeoHashEnabled(geoHashMapper.fieldType(), geoHashPrecision, enableGeoHashPrefix);
}
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/geo/GeoPointFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/geo/GeoPointFieldMapper.java
index 71309d2fa2d..9c8b4a1f468 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/geo/GeoPointFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/geo/GeoPointFieldMapper.java
@@ -20,9 +20,10 @@
package org.elasticsearch.index.mapper.geo;
import org.apache.lucene.document.FieldType;
-import org.apache.lucene.document.GeoPointField;
import org.apache.lucene.index.DocValuesType;
import org.apache.lucene.index.IndexOptions;
+import org.apache.lucene.spatial.geopoint.document.GeoPointField;
+import org.elasticsearch.Version;
import org.elasticsearch.common.Explicit;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.GeoUtils;
@@ -59,8 +60,6 @@ public class GeoPointFieldMapper extends BaseGeoPointFieldMapper {
FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
FIELD_TYPE.setTokenized(false);
FIELD_TYPE.setOmitNorms(true);
- FIELD_TYPE.setNumericType(FieldType.NumericType.LONG);
- FIELD_TYPE.setNumericPrecisionStep(GeoPointField.PRECISION_STEP);
FIELD_TYPE.setDocValuesType(DocValuesType.SORTED_NUMERIC);
FIELD_TYPE.setHasDocValues(true);
FIELD_TYPE.freeze();
@@ -83,6 +82,10 @@ public class GeoPointFieldMapper extends BaseGeoPointFieldMapper {
DoubleFieldMapper lonMapper, StringFieldMapper geoHashMapper, MultiFields multiFields, Explicit ignoreMalformed,
CopyTo copyTo) {
fieldType.setTokenized(false);
+ if (context.indexCreatedVersion().before(Version.V_2_3_0)) {
+ fieldType.setNumericPrecisionStep(GeoPointField.PRECISION_STEP);
+ fieldType.setNumericType(FieldType.NumericType.LONG);
+ }
setupFieldType(context);
return new GeoPointFieldMapper(simpleName, fieldType, defaultFieldType, indexSettings, latMapper, lonMapper,
geoHashMapper, multiFields, ignoreMalformed, copyTo);
@@ -90,6 +93,10 @@ public class GeoPointFieldMapper extends BaseGeoPointFieldMapper {
@Override
public GeoPointFieldMapper build(BuilderContext context) {
+ if (context.indexCreatedVersion().before(Version.V_2_3_0)) {
+ fieldType.setNumericPrecisionStep(GeoPointField.PRECISION_STEP);
+ fieldType.setNumericType(FieldType.NumericType.LONG);
+ }
return super.build(context);
}
}
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/geo/GeoShapeFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/geo/GeoShapeFieldMapper.java
index c98744bb759..bf699afa514 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/geo/GeoShapeFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/geo/GeoShapeFieldMapper.java
@@ -45,6 +45,7 @@ import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.ParseContext;
+import org.elasticsearch.index.mapper.core.DoubleFieldMapper;
import java.io.IOException;
import java.util.Iterator;
@@ -53,7 +54,6 @@ import java.util.Map;
import java.util.Objects;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.lenientNodeBooleanValue;
-import static org.elasticsearch.index.mapper.MapperBuilders.geoShapeField;
/**
@@ -160,7 +160,7 @@ public class GeoShapeFieldMapper extends FieldMapper {
@Override
public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException {
- Builder builder = geoShapeField(name);
+ Builder builder = new Builder(name);
for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = iterator.next();
String fieldName = Strings.toUnderscoreCase(entry.getKey());
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java
index e7cd1b107ae..66e754e5fda 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/internal/ParentFieldMapper.java
@@ -38,12 +38,11 @@ import org.elasticsearch.index.fielddata.FieldDataType;
import org.elasticsearch.index.mapper.ContentPath;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.Mapper;
-import org.elasticsearch.index.mapper.MapperBuilders;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MetadataFieldMapper;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.Uid;
-import org.elasticsearch.index.mapper.core.StringFieldMapper;
+import org.elasticsearch.index.mapper.core.KeywordFieldMapper;
import org.elasticsearch.index.query.QueryShardContext;
import java.io.IOException;
@@ -132,15 +131,15 @@ public class ParentFieldMapper extends MetadataFieldMapper {
@Override
public MetadataFieldMapper getDefault(Settings indexSettings, MappedFieldType fieldType, String typeName) {
- StringFieldMapper parentJoinField = createParentJoinFieldMapper(typeName, new BuilderContext(indexSettings, new ContentPath(0)));
+ KeywordFieldMapper parentJoinField = createParentJoinFieldMapper(typeName, new BuilderContext(indexSettings, new ContentPath(0)));
MappedFieldType childJoinFieldType = Defaults.FIELD_TYPE.clone();
childJoinFieldType.setName(joinField(null));
return new ParentFieldMapper(parentJoinField, childJoinFieldType, null, indexSettings);
}
}
- static StringFieldMapper createParentJoinFieldMapper(String docType, BuilderContext context) {
- StringFieldMapper.Builder parentJoinField = MapperBuilders.stringField(joinField(docType));
+ static KeywordFieldMapper createParentJoinFieldMapper(String docType, BuilderContext context) {
+ KeywordFieldMapper.Builder parentJoinField = new KeywordFieldMapper.Builder(joinField(docType));
parentJoinField.indexOptions(IndexOptions.NONE);
parentJoinField.docValues(true);
parentJoinField.fieldType().setDocValuesType(DocValuesType.SORTED);
@@ -206,9 +205,9 @@ public class ParentFieldMapper extends MetadataFieldMapper {
private final String parentType;
// has no impact of field data settings, is just here for creating a join field,
// the parent field mapper in the child type pointing to this type determines the field data settings for this join field
- private final StringFieldMapper parentJoinField;
+ private final KeywordFieldMapper parentJoinField;
- private ParentFieldMapper(StringFieldMapper parentJoinField, MappedFieldType childJoinFieldType, String parentType, Settings indexSettings) {
+ private ParentFieldMapper(KeywordFieldMapper parentJoinField, MappedFieldType childJoinFieldType, String parentType, Settings indexSettings) {
super(NAME, childJoinFieldType, Defaults.FIELD_TYPE, indexSettings);
this.parentType = parentType;
this.parentJoinField = parentJoinField;
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java
index fc9660d5c1d..9b8630040ff 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java
@@ -57,7 +57,6 @@ import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
-import static org.elasticsearch.index.mapper.MapperBuilders.ipField;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
/**
@@ -139,7 +138,7 @@ public class IpFieldMapper extends NumberFieldMapper {
public static class TypeParser implements Mapper.TypeParser {
@Override
public Mapper.Builder parse(String name, Map node, ParserContext parserContext) throws MapperParsingException {
- IpFieldMapper.Builder builder = ipField(name);
+ IpFieldMapper.Builder builder = new Builder(name);
parseNumberField(builder, name, node, parserContext);
for (Iterator> iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = iterator.next();
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/object/ObjectMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/object/ObjectMapper.java
index b5934a40116..31dc34e4208 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/object/ObjectMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/object/ObjectMapper.java
@@ -50,7 +50,6 @@ import java.util.Locale;
import java.util.Map;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.lenientNodeBooleanValue;
-import static org.elasticsearch.index.mapper.MapperBuilders.object;
/**
*
@@ -300,7 +299,7 @@ public class ObjectMapper extends Mapper implements AllFieldMapper.IncludeInAll,
}
protected Builder createBuilder(String name) {
- return object(name);
+ return new Builder(name);
}
}
diff --git a/core/src/main/java/org/elasticsearch/index/percolator/PercolatorFieldMapper.java b/core/src/main/java/org/elasticsearch/index/percolator/PercolatorFieldMapper.java
index 9a103195746..f44d454655e 100644
--- a/core/src/main/java/org/elasticsearch/index/percolator/PercolatorFieldMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/percolator/PercolatorFieldMapper.java
@@ -26,10 +26,9 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.Mapper;
-import org.elasticsearch.index.mapper.MapperBuilders;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.ParseContext;
-import org.elasticsearch.index.mapper.core.StringFieldMapper;
+import org.elasticsearch.index.mapper.core.KeywordFieldMapper;
import org.elasticsearch.index.query.QueryShardContext;
import java.io.IOException;
@@ -61,17 +60,16 @@ public class PercolatorFieldMapper extends FieldMapper {
@Override
public PercolatorFieldMapper build(BuilderContext context) {
context.path().add(name);
- StringFieldMapper extractedTermsField = createStringFieldBuilder(EXTRACTED_TERMS_FIELD_NAME).build(context);
- StringFieldMapper unknownQueryField = createStringFieldBuilder(UNKNOWN_QUERY_FIELD_NAME).build(context);
+ KeywordFieldMapper extractedTermsField = createStringFieldBuilder(EXTRACTED_TERMS_FIELD_NAME).build(context);
+ KeywordFieldMapper unknownQueryField = createStringFieldBuilder(UNKNOWN_QUERY_FIELD_NAME).build(context);
context.path().remove();
return new PercolatorFieldMapper(name(), fieldType, defaultFieldType, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo, queryShardContext, extractedTermsField, unknownQueryField);
}
- static StringFieldMapper.Builder createStringFieldBuilder(String name) {
- StringFieldMapper.Builder queryMetaDataFieldBuilder = MapperBuilders.stringField(name);
+ static KeywordFieldMapper.Builder createStringFieldBuilder(String name) {
+ KeywordFieldMapper.Builder queryMetaDataFieldBuilder = new KeywordFieldMapper.Builder(name);
queryMetaDataFieldBuilder.docValues(false);
queryMetaDataFieldBuilder.store(false);
- queryMetaDataFieldBuilder.tokenized(false);
queryMetaDataFieldBuilder.indexOptions(IndexOptions.DOCS);
return queryMetaDataFieldBuilder;
}
@@ -111,10 +109,10 @@ public class PercolatorFieldMapper extends FieldMapper {
private final boolean mapUnmappedFieldAsString;
private final QueryShardContext queryShardContext;
- private final StringFieldMapper queryTermsField;
- private final StringFieldMapper unknownQueryField;
+ private final KeywordFieldMapper queryTermsField;
+ private final KeywordFieldMapper unknownQueryField;
- public PercolatorFieldMapper(String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType, Settings indexSettings, MultiFields multiFields, CopyTo copyTo, QueryShardContext queryShardContext, StringFieldMapper queryTermsField, StringFieldMapper unknownQueryField) {
+ public PercolatorFieldMapper(String simpleName, MappedFieldType fieldType, MappedFieldType defaultFieldType, Settings indexSettings, MultiFields multiFields, CopyTo copyTo, QueryShardContext queryShardContext, KeywordFieldMapper queryTermsField, KeywordFieldMapper unknownQueryField) {
super(simpleName, fieldType, defaultFieldType, indexSettings, multiFields, copyTo);
this.queryShardContext = queryShardContext;
this.queryTermsField = queryTermsField;
diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java
index a0246f1f834..05c2a74bb9f 100644
--- a/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/GeoBoundingBoxQueryBuilder.java
@@ -19,7 +19,8 @@
package org.elasticsearch.index.query;
-import org.apache.lucene.search.GeoPointInBBoxQuery;
+import org.apache.lucene.spatial.geopoint.document.GeoPointField;
+import org.apache.lucene.spatial.geopoint.search.GeoPointInBBoxQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.Version;
import org.elasticsearch.common.Numbers;
@@ -105,7 +106,7 @@ public class GeoBoundingBoxQueryBuilder extends AbstractQueryBuilder use prefix encoded postings format
+ final GeoPointField.TermEncoding encoding = (indexVersionCreated.before(Version.V_2_3_0)) ?
+ GeoPointField.TermEncoding.NUMERIC : GeoPointField.TermEncoding.PREFIX;
+ return new GeoPointInBBoxQuery(fieldType.name(), encoding, luceneTopLeft.lon(), luceneBottomRight.lat(),
luceneBottomRight.lon(), luceneTopLeft.lat());
}
diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java
index 43f55dc034b..784c924efcf 100644
--- a/core/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/GeoDistanceQueryBuilder.java
@@ -19,7 +19,8 @@
package org.elasticsearch.index.query;
-import org.apache.lucene.search.GeoPointDistanceQuery;
+import org.apache.lucene.spatial.geopoint.document.GeoPointField;
+import org.apache.lucene.spatial.geopoint.search.GeoPointDistanceQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.Version;
import org.elasticsearch.common.Strings;
@@ -229,14 +230,19 @@ public class GeoDistanceQueryBuilder extends AbstractQueryBuilder use prefix encoded postings format
+ final GeoPointField.TermEncoding encoding = (indexVersionCreated.before(Version.V_2_3_0)) ?
+ GeoPointField.TermEncoding.NUMERIC : GeoPointField.TermEncoding.PREFIX;
normDistance = GeoUtils.maxRadialDistance(center, normDistance);
- return new GeoPointDistanceQuery(fieldType.name(), center.lon(), center.lat(), normDistance);
+ return new GeoPointDistanceQuery(fieldType.name(), encoding, center.lon(), center.lat(), normDistance);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java
index dc1c3d69817..e7b3dca7051 100644
--- a/core/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/GeoDistanceRangeQueryBuilder.java
@@ -19,9 +19,10 @@
package org.elasticsearch.index.query;
-import org.apache.lucene.search.GeoPointDistanceRangeQuery;
import org.apache.lucene.search.Query;
-import org.apache.lucene.util.GeoDistanceUtils;
+import org.apache.lucene.spatial.geopoint.document.GeoPointField;
+import org.apache.lucene.spatial.geopoint.search.GeoPointDistanceRangeQuery;
+import org.apache.lucene.spatial.util.GeoDistanceUtils;
import org.elasticsearch.Version;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.geo.GeoDistance;
@@ -41,7 +42,7 @@ import java.io.IOException;
import java.util.Locale;
import java.util.Objects;
-import static org.apache.lucene.util.GeoUtils.TOLERANCE;
+import static org.apache.lucene.spatial.util.GeoEncodingUtils.TOLERANCE;
public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder {
@@ -267,16 +268,22 @@ public class GeoDistanceRangeQueryBuilder extends AbstractQueryBuilder use prefix encoded postings format
+ final GeoPointField.TermEncoding encoding = (indexVersionCreated.before(Version.V_2_3_0)) ?
+ GeoPointField.TermEncoding.NUMERIC : GeoPointField.TermEncoding.PREFIX;
+
+ return new GeoPointDistanceRangeQuery(fieldType.name(), encoding, point.lon(), point.lat(),
+ (includeLower) ? fromValue : fromValue + TOLERANCE,
+ (includeUpper) ? toValue : toValue - TOLERANCE);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/GeoPolygonQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/GeoPolygonQueryBuilder.java
index 8817ac69894..53fab5a3f4a 100644
--- a/core/src/main/java/org/elasticsearch/index/query/GeoPolygonQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/GeoPolygonQueryBuilder.java
@@ -19,7 +19,8 @@
package org.elasticsearch.index.query;
-import org.apache.lucene.search.GeoPointInPolygonQuery;
+import org.apache.lucene.spatial.geopoint.document.GeoPointField;
+import org.apache.lucene.spatial.geopoint.search.GeoPointInPolygonQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.Version;
import org.elasticsearch.common.Strings;
@@ -136,7 +137,8 @@ public class GeoPolygonQueryBuilder extends AbstractQueryBuilder use prefix encoded postings format
+ final GeoPointField.TermEncoding encoding = (indexVersionCreated.before(Version.V_2_3_0)) ?
+ GeoPointField.TermEncoding.NUMERIC : GeoPointField.TermEncoding.PREFIX;
+ return new GeoPointInPolygonQuery(fieldType.name(), encoding, lons, lats);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java b/core/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java
index 07e92a6dc16..9f0d259374b 100644
--- a/core/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java
+++ b/core/src/main/java/org/elasticsearch/index/query/GeohashCellQuery.java
@@ -20,7 +20,7 @@
package org.elasticsearch.index.query;
import org.apache.lucene.search.Query;
-import org.apache.lucene.util.GeoHashUtils;
+import org.apache.lucene.spatial.util.GeoHashUtils;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryBuilders.java b/core/src/main/java/org/elasticsearch/index/query/QueryBuilders.java
index 03ccebf0479..21c1f3ff695 100644
--- a/core/src/main/java/org/elasticsearch/index/query/QueryBuilders.java
+++ b/core/src/main/java/org/elasticsearch/index/query/QueryBuilders.java
@@ -27,7 +27,7 @@ import org.elasticsearch.index.query.MoreLikeThisQueryBuilder.Item;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;
import org.elasticsearch.index.search.MatchQuery;
-import org.elasticsearch.indices.cache.query.terms.TermsLookup;
+import org.elasticsearch.indices.TermsLookup;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.Template;
diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java b/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java
index 4701cdfeecc..3aa5f25004d 100644
--- a/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java
+++ b/core/src/main/java/org/elasticsearch/index/query/QueryShardContext.java
@@ -44,7 +44,6 @@ import org.elasticsearch.index.fielddata.IndexFieldDataService;
import org.elasticsearch.index.mapper.ContentPath;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.Mapper;
-import org.elasticsearch.index.mapper.MapperBuilders;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.core.StringFieldMapper;
import org.elasticsearch.index.mapper.object.ObjectMapper;
@@ -278,7 +277,7 @@ public class QueryShardContext {
if (fieldMapping != null || allowUnmappedFields) {
return fieldMapping;
} else if (mapUnmappedFieldAsString) {
- StringFieldMapper.Builder builder = MapperBuilders.stringField(name);
+ StringFieldMapper.Builder builder = new StringFieldMapper.Builder(name);
return builder.build(new Mapper.BuilderContext(indexSettings.getSettings(), new ContentPath(1))).fieldType();
} else {
throw new QueryShardException(this, "No field mapping can be found for the field with name [{}]", name);
diff --git a/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java b/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java
index 326a6ed8b8e..67e5b5643a5 100644
--- a/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/TermsQueryBuilder.java
@@ -37,8 +37,7 @@ import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.index.mapper.MappedFieldType;
-import org.elasticsearch.indices.cache.query.terms.TermsLookup;
-import org.elasticsearch.search.internal.SearchContext;
+import org.elasticsearch.indices.TermsLookup;
import java.io.IOException;
import java.util.ArrayList;
diff --git a/core/src/main/java/org/elasticsearch/index/query/TermsQueryParser.java b/core/src/main/java/org/elasticsearch/index/query/TermsQueryParser.java
index 310256556c8..d92b87d3af4 100644
--- a/core/src/main/java/org/elasticsearch/index/query/TermsQueryParser.java
+++ b/core/src/main/java/org/elasticsearch/index/query/TermsQueryParser.java
@@ -21,7 +21,7 @@ package org.elasticsearch.index.query;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentParser;
-import org.elasticsearch.indices.cache.query.terms.TermsLookup;
+import org.elasticsearch.indices.TermsLookup;
import java.io.IOException;
import java.util.ArrayList;
diff --git a/core/src/main/java/org/elasticsearch/index/shard/IndexShard.java b/core/src/main/java/org/elasticsearch/index/shard/IndexShard.java
index 0f47eec6b25..954c2f8af4b 100644
--- a/core/src/main/java/org/elasticsearch/index/shard/IndexShard.java
+++ b/core/src/main/java/org/elasticsearch/index/shard/IndexShard.java
@@ -224,7 +224,7 @@ public class IndexShard extends AbstractIndexShardComponent {
this.getService = new ShardGetService(indexSettings, this, mapperService);
this.searchService = new ShardSearchStats(slowLog);
this.shardWarmerService = new ShardIndexWarmerService(shardId, indexSettings);
- this.shardQueryCache = new ShardRequestCache(shardId, indexSettings);
+ this.shardQueryCache = new ShardRequestCache();
this.shardFieldData = new ShardFieldData();
this.indexFieldDataService = indexFieldDataService;
this.shardBitsetFilterCache = new ShardBitsetFilterCache(shardId, indexSettings);
diff --git a/core/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java b/core/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java
index 271d5a353bc..e3885816cd2 100644
--- a/core/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java
+++ b/core/src/main/java/org/elasticsearch/index/termvectors/TermVectorsService.java
@@ -44,6 +44,7 @@ import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.ParsedDocument;
import org.elasticsearch.index.mapper.Uid;
+import org.elasticsearch.index.mapper.core.KeywordFieldMapper;
import org.elasticsearch.index.mapper.core.StringFieldMapper;
import org.elasticsearch.index.mapper.internal.UidFieldMapper;
import org.elasticsearch.index.shard.IndexShard;
@@ -158,7 +159,8 @@ public class TermVectorsService {
private static boolean isValidField(MappedFieldType fieldType) {
// must be a string
- if (!(fieldType instanceof StringFieldMapper.StringFieldType)) {
+ if (fieldType instanceof StringFieldMapper.StringFieldType == false
+ && fieldType instanceof KeywordFieldMapper.KeywordFieldType == false) {
return false;
}
// and must be indexed
diff --git a/core/src/main/java/org/elasticsearch/indices/IndicesModule.java b/core/src/main/java/org/elasticsearch/indices/IndicesModule.java
index b94ef19ec23..955a95676bd 100644
--- a/core/src/main/java/org/elasticsearch/indices/IndicesModule.java
+++ b/core/src/main/java/org/elasticsearch/indices/IndicesModule.java
@@ -34,6 +34,7 @@ import org.elasticsearch.index.mapper.core.DateFieldMapper;
import org.elasticsearch.index.mapper.core.DoubleFieldMapper;
import org.elasticsearch.index.mapper.core.FloatFieldMapper;
import org.elasticsearch.index.mapper.core.IntegerFieldMapper;
+import org.elasticsearch.index.mapper.core.KeywordFieldMapper;
import org.elasticsearch.index.mapper.core.LongFieldMapper;
import org.elasticsearch.index.mapper.core.ShortFieldMapper;
import org.elasticsearch.index.mapper.core.StringFieldMapper;
@@ -60,7 +61,7 @@ import org.elasticsearch.indices.flush.SyncedFlushService;
import org.elasticsearch.indices.mapper.MapperRegistry;
import org.elasticsearch.indices.recovery.RecoverySettings;
import org.elasticsearch.indices.recovery.RecoverySource;
-import org.elasticsearch.indices.recovery.RecoveryTarget;
+import org.elasticsearch.indices.recovery.RecoveryTargetService;
import org.elasticsearch.indices.store.IndicesStore;
import org.elasticsearch.indices.store.TransportNodesListShardStoreMetaData;
import org.elasticsearch.indices.ttl.IndicesTTLService;
@@ -96,6 +97,7 @@ public class IndicesModule extends AbstractModule {
registerMapper(DateFieldMapper.CONTENT_TYPE, new DateFieldMapper.TypeParser());
registerMapper(IpFieldMapper.CONTENT_TYPE, new IpFieldMapper.TypeParser());
registerMapper(StringFieldMapper.CONTENT_TYPE, new StringFieldMapper.TypeParser());
+ registerMapper(KeywordFieldMapper.CONTENT_TYPE, new KeywordFieldMapper.TypeParser());
registerMapper(TokenCountFieldMapper.CONTENT_TYPE, new TokenCountFieldMapper.TypeParser());
registerMapper(ObjectMapper.CONTENT_TYPE, new ObjectMapper.TypeParser());
registerMapper(ObjectMapper.NESTED_CONTENT_TYPE, new ObjectMapper.TypeParser());
@@ -153,7 +155,7 @@ public class IndicesModule extends AbstractModule {
bind(IndicesService.class).asEagerSingleton();
bind(RecoverySettings.class).asEagerSingleton();
- bind(RecoveryTarget.class).asEagerSingleton();
+ bind(RecoveryTargetService.class).asEagerSingleton();
bind(RecoverySource.class).asEagerSingleton();
bind(IndicesStore.class).asEagerSingleton();
bind(IndicesClusterStateService.class).asEagerSingleton();
diff --git a/core/src/main/java/org/elasticsearch/indices/cache/query/IndicesQueryCache.java b/core/src/main/java/org/elasticsearch/indices/IndicesQueryCache.java
similarity index 99%
rename from core/src/main/java/org/elasticsearch/indices/cache/query/IndicesQueryCache.java
rename to core/src/main/java/org/elasticsearch/indices/IndicesQueryCache.java
index 718f4db9c4e..926ff482248 100644
--- a/core/src/main/java/org/elasticsearch/indices/cache/query/IndicesQueryCache.java
+++ b/core/src/main/java/org/elasticsearch/indices/IndicesQueryCache.java
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.elasticsearch.indices.cache.query;
+package org.elasticsearch.indices;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Term;
diff --git a/core/src/main/java/org/elasticsearch/indices/IndicesRequestCache.java b/core/src/main/java/org/elasticsearch/indices/IndicesRequestCache.java
new file mode 100644
index 00000000000..575153c8ada
--- /dev/null
+++ b/core/src/main/java/org/elasticsearch/indices/IndicesRequestCache.java
@@ -0,0 +1,337 @@
+/*
+ * 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.indices;
+
+import com.carrotsearch.hppc.ObjectHashSet;
+import com.carrotsearch.hppc.ObjectSet;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.util.Accountable;
+import org.apache.lucene.util.RamUsageEstimator;
+import org.elasticsearch.common.bytes.BytesReference;
+import org.elasticsearch.common.cache.Cache;
+import org.elasticsearch.common.cache.CacheBuilder;
+import org.elasticsearch.common.cache.CacheLoader;
+import org.elasticsearch.common.cache.RemovalListener;
+import org.elasticsearch.common.cache.RemovalNotification;
+import org.elasticsearch.common.component.AbstractComponent;
+import org.elasticsearch.common.lucene.index.ElasticsearchDirectoryReader;
+import org.elasticsearch.common.settings.Setting;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.common.unit.ByteSizeValue;
+import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * The indices request cache allows to cache a shard level request stage responses, helping with improving
+ * similar requests that are potentially expensive (because of aggs for example). The cache is fully coherent
+ * with the semantics of NRT (the index reader version is part of the cache key), and relies on size based
+ * eviction to evict old reader associated cache entries as well as scheduler reaper to clean readers that
+ * are no longer used or closed shards.
+ *
+ * Currently, the cache is only enabled for count requests, and can only be opted in on an index
+ * level setting that can be dynamically changed and defaults to false.
+ *
+ * There are still several TODOs left in this class, some easily addressable, some more complex, but the support
+ * is functional.
+ */
+public final class IndicesRequestCache extends AbstractComponent implements RemovalListener, Closeable {
+
+ /**
+ * A setting to enable or disable request caching on an index level. Its dynamic by default
+ * since we are checking on the cluster state IndexMetaData always.
+ */
+ public static final Setting INDEX_CACHE_REQUEST_ENABLED_SETTING = Setting.boolSetting("index.requests.cache.enable",
+ false, true, Setting.Scope.INDEX);
+ public static final Setting INDICES_CACHE_QUERY_SIZE = Setting.byteSizeSetting("indices.requests.cache.size", "1%",
+ false, Setting.Scope.CLUSTER);
+ public static final Setting INDICES_CACHE_QUERY_EXPIRE = Setting.positiveTimeSetting("indices.requests.cache.expire",
+ new TimeValue(0), false, Setting.Scope.CLUSTER);
+
+ private final ConcurrentMap registeredClosedListeners = ConcurrentCollections.newConcurrentMap();
+ private final Set keysToClean = ConcurrentCollections.newConcurrentSet();
+ private final ByteSizeValue size;
+ private final TimeValue expire;
+ private final Cache cache;
+
+ IndicesRequestCache(Settings settings) {
+ super(settings);
+ this.size = INDICES_CACHE_QUERY_SIZE.get(settings);
+ this.expire = INDICES_CACHE_QUERY_EXPIRE.exists(settings) ? INDICES_CACHE_QUERY_EXPIRE.get(settings) : null;
+ long sizeInBytes = size.bytes();
+ CacheBuilder cacheBuilder = CacheBuilder.builder()
+ .setMaximumWeight(sizeInBytes).weigher((k, v) -> k.ramBytesUsed() + v.ramBytesUsed()).removalListener(this);
+ if (expire != null) {
+ cacheBuilder.setExpireAfterAccess(TimeUnit.MILLISECONDS.toNanos(expire.millis()));
+ }
+ cache = cacheBuilder.build();
+ }
+
+ @Override
+ public void close() {
+ cache.invalidateAll();
+ }
+
+ void clear(CacheEntity entity) {
+ keysToClean.add(new CleanupKey(entity, -1));
+ cleanCache();
+ }
+
+ @Override
+ public void onRemoval(RemovalNotification notification) {
+ notification.getKey().entity.onRemoval(notification);
+ }
+
+ BytesReference getOrCompute(CacheEntity cacheEntity, DirectoryReader reader, BytesReference cacheKey) throws Exception {
+ final Key key = new Key(cacheEntity, reader.getVersion(), cacheKey);
+ Loader loader = new Loader(cacheEntity);
+ Value value = cache.computeIfAbsent(key, loader);
+ if (loader.isLoaded()) {
+ key.entity.onMiss();
+ // see if its the first time we see this reader, and make sure to register a cleanup key
+ CleanupKey cleanupKey = new CleanupKey(cacheEntity, reader.getVersion());
+ if (!registeredClosedListeners.containsKey(cleanupKey)) {
+ Boolean previous = registeredClosedListeners.putIfAbsent(cleanupKey, Boolean.TRUE);
+ if (previous == null) {
+ ElasticsearchDirectoryReader.addReaderCloseListener(reader, cleanupKey);
+ }
+ }
+ } else {
+ key.entity.onHit();
+ }
+ return value.reference;
+ }
+
+ private static class Loader implements CacheLoader {
+
+ private final CacheEntity entity;
+ private boolean loaded;
+
+ Loader(CacheEntity entity) {
+ this.entity = entity;
+ }
+
+ public boolean isLoaded() {
+ return this.loaded;
+ }
+
+ @Override
+ public Value load(Key key) throws Exception {
+ Value value = entity.loadValue();
+ entity.onCached(key, value);
+ loaded = true;
+ return value;
+ }
+ }
+
+ /**
+ * Basic interface to make this cache testable.
+ */
+ interface CacheEntity {
+ /**
+ * Loads the actual cache value. this is the heavy lifting part.
+ */
+ Value loadValue() throws IOException;
+
+ /**
+ * Called after the value was loaded via {@link #loadValue()}
+ */
+ void onCached(Key key, Value value);
+
+ /**
+ * Returns true iff the resource behind this entity is still open ie.
+ * entities assiciated with it can remain in the cache. ie. IndexShard is still open.
+ */
+ boolean isOpen();
+
+ /**
+ * Returns the cache identity. this is, similar to {@link #isOpen()} the resource identity behind this cache entity.
+ * For instance IndexShard is the identity while a CacheEntity is per DirectoryReader. Yet, we group by IndexShard instance.
+ */
+ Object getCacheIdentity();
+
+ /**
+ * Called each time this entity has a cache hit.
+ */
+ void onHit();
+
+ /**
+ * Called each time this entity has a cache miss.
+ */
+ void onMiss();
+
+ /**
+ * Called when this entity instance is removed
+ */
+ void onRemoval(RemovalNotification notification);
+ }
+
+
+
+ static class Value implements Accountable {
+ final BytesReference reference;
+ final long ramBytesUsed;
+
+ Value(BytesReference reference, long ramBytesUsed) {
+ this.reference = reference;
+ this.ramBytesUsed = ramBytesUsed;
+ }
+
+ @Override
+ public long ramBytesUsed() {
+ return ramBytesUsed;
+ }
+
+ @Override
+ public Collection getChildResources() {
+ return Collections.emptyList();
+ }
+ }
+
+ static class Key implements Accountable {
+ public final CacheEntity entity; // use as identity equality
+ public final long readerVersion; // use the reader version to now keep a reference to a "short" lived reader until its reaped
+ public final BytesReference value;
+
+ Key(CacheEntity entity, long readerVersion, BytesReference value) {
+ this.entity = entity;
+ this.readerVersion = readerVersion;
+ this.value = value;
+ }
+
+ @Override
+ public long ramBytesUsed() {
+ return RamUsageEstimator.NUM_BYTES_OBJECT_REF + RamUsageEstimator.NUM_BYTES_LONG + value.length();
+ }
+
+ @Override
+ public Collection getChildResources() {
+ // TODO: more detailed ram usage?
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ Key key = (Key) o;
+ if (readerVersion != key.readerVersion) return false;
+ if (!entity.getCacheIdentity().equals(key.entity.getCacheIdentity())) return false;
+ if (!value.equals(key.value)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = entity.getCacheIdentity().hashCode();
+ result = 31 * result + Long.hashCode(readerVersion);
+ result = 31 * result + value.hashCode();
+ return result;
+ }
+ }
+
+ private class CleanupKey implements IndexReader.ReaderClosedListener {
+ final CacheEntity entity;
+ final long readerVersion; // use the reader version to now keep a reference to a "short" lived reader until its reaped
+
+ private CleanupKey(CacheEntity entity, long readerVersion) {
+ this.entity = entity;
+ this.readerVersion = readerVersion;
+ }
+
+ @Override
+ public void onClose(IndexReader reader) {
+ Boolean remove = registeredClosedListeners.remove(this);
+ if (remove != null) {
+ keysToClean.add(this);
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ CleanupKey that = (CleanupKey) o;
+ if (readerVersion != that.readerVersion) return false;
+ if (!entity.getCacheIdentity().equals(that.entity.getCacheIdentity())) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = entity.getCacheIdentity().hashCode();
+ result = 31 * result + Long.hashCode(readerVersion);
+ return result;
+ }
+ }
+
+
+
+ synchronized void cleanCache() {
+ final ObjectSet currentKeysToClean = new ObjectHashSet<>();
+ final ObjectSet