Remove `_timestamp` and `_ttl` on 5.x indices. #18980
This removes the ability to use `_timestamp` and `_ttl` on indices created on or after 5.0. Closes #18280
This commit is contained in:
parent
5dc88ffd26
commit
db9af54ec0
|
@ -21,6 +21,7 @@ package org.elasticsearch.index.mapper.internal;
|
|||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.index.IndexOptions;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.lucene.Lucene;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
|
@ -100,6 +101,9 @@ public class TTLFieldMapper extends MetadataFieldMapper {
|
|||
public static class TypeParser implements MetadataFieldMapper.TypeParser {
|
||||
@Override
|
||||
public MetadataFieldMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
if (parserContext.indexVersionCreated().onOrAfter(Version.V_5_0_0_alpha4)) {
|
||||
throw new IllegalArgumentException("[_ttl] is removed in 5.0. As a replacement, you should use time based indexes or cron a delete-by-query with a range query on a timestamp field.");
|
||||
}
|
||||
Builder builder = new Builder();
|
||||
for (Iterator<Map.Entry<String, Object>> iterator = node.entrySet().iterator(); iterator.hasNext();) {
|
||||
Map.Entry<String, Object> entry = iterator.next();
|
||||
|
@ -165,6 +169,9 @@ public class TTLFieldMapper extends MetadataFieldMapper {
|
|||
private TTLFieldMapper(MappedFieldType fieldType, EnabledAttributeMapper enabled, long defaultTTL,
|
||||
Settings indexSettings) {
|
||||
super(NAME, fieldType, Defaults.TTL_FIELD_TYPE, indexSettings);
|
||||
if (enabled.enabled && Version.indexCreated(indexSettings).onOrAfter(Version.V_5_0_0_alpha4)) {
|
||||
throw new IllegalArgumentException("[_ttl] is removed in 5.0. As a replacement, you should use time based indexes or cron a delete-by-query with a range query on a timestamp field.");
|
||||
}
|
||||
this.enabledState = enabled;
|
||||
this.defaultTTL = defaultTTL;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.index.mapper.internal;
|
|||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.NumericDocValuesField;
|
||||
import org.apache.lucene.index.IndexOptions;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.TimestampParsingException;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
|
||||
|
@ -126,6 +127,9 @@ public class TimestampFieldMapper extends MetadataFieldMapper {
|
|||
public static class TypeParser implements MetadataFieldMapper.TypeParser {
|
||||
@Override
|
||||
public MetadataFieldMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
if (parserContext.indexVersionCreated().onOrAfter(Version.V_5_0_0_alpha4)) {
|
||||
throw new IllegalArgumentException("[_timestamp] is removed in 5.0. As a replacement, you can use an ingest pipeline to add a field with the current timestamp to your documents.");
|
||||
}
|
||||
Builder builder = new Builder(parserContext.mapperService().fullName(NAME), parserContext.mapperService().getIndexSettings().getSettings());
|
||||
boolean defaultSet = false;
|
||||
Boolean ignoreMissing = null;
|
||||
|
@ -200,6 +204,9 @@ public class TimestampFieldMapper extends MetadataFieldMapper {
|
|||
private TimestampFieldMapper(MappedFieldType fieldType, MappedFieldType defaultFieldType, EnabledAttributeMapper enabledState,
|
||||
String defaultTimestamp, Boolean ignoreMissing, Settings indexSettings) {
|
||||
super(NAME, fieldType, defaultFieldType, indexSettings);
|
||||
if (enabledState.enabled && Version.indexCreated(indexSettings).onOrAfter(Version.V_5_0_0_alpha4)) {
|
||||
throw new IllegalArgumentException("[_timestamp] is removed in 5.0. As a replacement, you can use an ingest pipeline to add a field with the current timestamp to your documents.");
|
||||
}
|
||||
this.enabledState = enabledState;
|
||||
this.defaultTimestamp = defaultTimestamp;
|
||||
this.ignoreMissing = ignoreMissing;
|
||||
|
|
|
@ -1035,13 +1035,13 @@ public class IndexAliasesIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void testAliasFilterWithNowInRangeFilterAndQuery() throws Exception {
|
||||
assertAcked(prepareCreate("my-index").addMapping("my-type", "_timestamp", "enabled=true"));
|
||||
assertAcked(admin().indices().prepareAliases().addAlias("my-index", "filter1", rangeQuery("_timestamp").from("now-1d").to("now")));
|
||||
assertAcked(admin().indices().prepareAliases().addAlias("my-index", "filter2", rangeQuery("_timestamp").from("now-1d").to("now")));
|
||||
assertAcked(prepareCreate("my-index").addMapping("my-type", "timestamp", "type=date"));
|
||||
assertAcked(admin().indices().prepareAliases().addAlias("my-index", "filter1", rangeQuery("timestamp").from("2016-12-01").to("2016-12-31")));
|
||||
assertAcked(admin().indices().prepareAliases().addAlias("my-index", "filter2", rangeQuery("timestamp").from("2016-01-01").to("2016-12-31")));
|
||||
|
||||
final int numDocs = scaledRandomIntBetween(5, 52);
|
||||
for (int i = 1; i <= numDocs; i++) {
|
||||
client().prepareIndex("my-index", "my-type").setCreate(true).setSource("{}").get();
|
||||
client().prepareIndex("my-index", "my-type").setCreate(true).setSource("timestamp", "2016-12-12").get();
|
||||
if (i % 2 == 0) {
|
||||
refresh();
|
||||
SearchResponse response = client().prepareSearch("filter1").get();
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
|
|||
import org.elasticsearch.test.ESIntegTestCase.Scope;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
@ -111,16 +112,18 @@ public class SpecificMasterNodesIT extends ESIntegTestCase {
|
|||
internalCluster().startNode(settingsBuilder().put(Node.NODE_DATA_SETTING.getKey(), true).put(Node.NODE_MASTER_SETTING.getKey(), false));
|
||||
|
||||
createIndex("test");
|
||||
assertAcked(client().admin().indices().preparePutMapping("test").setType("_default_").setSource("_timestamp", "enabled=true"));
|
||||
assertAcked(client().admin().indices().preparePutMapping("test").setType("_default_").setSource("timestamp", "type=date"));
|
||||
|
||||
MappingMetaData defaultMapping = client().admin().cluster().prepareState().get().getState().getMetaData().getIndices().get("test").getMappings().get("_default_");
|
||||
assertThat(defaultMapping.getSourceAsMap().get("_timestamp"), notNullValue());
|
||||
Map<?,?> properties = (Map<?, ?>) defaultMapping.getSourceAsMap().get("properties");
|
||||
assertThat(properties.get("timestamp"), notNullValue());
|
||||
|
||||
assertAcked(client().admin().indices().preparePutMapping("test").setType("_default_").setSource("_timestamp", "enabled=true"));
|
||||
assertAcked(client().admin().indices().preparePutMapping("test").setType("_default_").setSource("timestamp", "type=date"));
|
||||
|
||||
assertAcked(client().admin().indices().preparePutMapping("test").setType("type1").setSource("foo", "enabled=true"));
|
||||
MappingMetaData type1Mapping = client().admin().cluster().prepareState().get().getState().getMetaData().getIndices().get("test").getMappings().get("type1");
|
||||
assertThat(type1Mapping.getSourceAsMap().get("_timestamp"), notNullValue());
|
||||
properties = (Map<?, ?>) type1Mapping.getSourceAsMap().get("properties");
|
||||
assertThat(properties.get("timestamp"), notNullValue());
|
||||
}
|
||||
|
||||
public void testAliasFilterValidation() throws Exception {
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
package org.elasticsearch.get;
|
||||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.ShardOperationFailedException;
|
||||
import org.elasticsearch.action.admin.indices.alias.Alias;
|
||||
import org.elasticsearch.action.admin.indices.flush.FlushResponse;
|
||||
|
@ -30,7 +29,6 @@ import org.elasticsearch.action.get.GetResponse;
|
|||
import org.elasticsearch.action.get.MultiGetRequest;
|
||||
import org.elasticsearch.action.get.MultiGetRequestBuilder;
|
||||
import org.elasticsearch.action.get.MultiGetResponse;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
|
@ -40,15 +38,11 @@ import org.elasticsearch.common.unit.TimeValue;
|
|||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.index.engine.VersionConflictEngineException;
|
||||
import org.elasticsearch.index.mapper.internal.TimestampFieldMapper;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
import org.elasticsearch.test.InternalSettingsPlugin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Collections.singleton;
|
||||
|
@ -57,7 +51,6 @@ import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcke
|
|||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasKey;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
@ -536,7 +529,7 @@ public class GetActionIT extends ESIntegTestCase {
|
|||
public void testGetFieldsMetaData() throws Exception {
|
||||
assertAcked(prepareCreate("test")
|
||||
.addMapping("parent")
|
||||
.addMapping("my-type1", "_timestamp", "enabled=true", "_ttl", "enabled=true", "_parent", "type=parent")
|
||||
.addMapping("my-type1", "_parent", "type=parent")
|
||||
.addAlias(new Alias("alias"))
|
||||
.setSettings(Settings.builder().put("index.refresh_interval", -1)));
|
||||
|
||||
|
@ -557,12 +550,6 @@ public class GetActionIT extends ESIntegTestCase {
|
|||
assertThat(getResponse.getField("field1").getValue().toString(), equalTo("value"));
|
||||
assertThat(getResponse.getField("_routing").isMetadataField(), equalTo(true));
|
||||
assertThat(getResponse.getField("_routing").getValue().toString(), equalTo("1"));
|
||||
assertThat(getResponse.getField("_timestamp").isMetadataField(), equalTo(true));
|
||||
assertThat(getResponse.getField("_timestamp").getValue().toString(), equalTo("205097"));
|
||||
assertThat(getResponse.getField("_ttl").isMetadataField(), equalTo(true));
|
||||
// TODO: _ttl should return the original value, but it does not work today because
|
||||
// it would use now() instead of the value of _timestamp to rebase
|
||||
// assertThat(getResponse.getField("_ttl").getValue().toString(), equalTo("10000000205097"));
|
||||
assertThat(getResponse.getField("_parent").isMetadataField(), equalTo(true));
|
||||
assertThat(getResponse.getField("_parent").getValue().toString(), equalTo("parent_1"));
|
||||
|
||||
|
@ -577,12 +564,6 @@ public class GetActionIT extends ESIntegTestCase {
|
|||
assertThat(getResponse.getField("field1").getValue().toString(), equalTo("value"));
|
||||
assertThat(getResponse.getField("_routing").isMetadataField(), equalTo(true));
|
||||
assertThat(getResponse.getField("_routing").getValue().toString(), equalTo("1"));
|
||||
assertThat(getResponse.getField("_timestamp").isMetadataField(), equalTo(true));
|
||||
assertThat(getResponse.getField("_timestamp").getValue().toString(), equalTo("205097"));
|
||||
assertThat(getResponse.getField("_ttl").isMetadataField(), equalTo(true));
|
||||
// TODO: _ttl should return the original value, but it does not work today because
|
||||
// it would use now() instead of the value of _timestamp to rebase
|
||||
//assertThat(getResponse.getField("_ttl").getValue().toString(), equalTo("10000000000000"));
|
||||
assertThat(getResponse.getField("_parent").isMetadataField(), equalTo(true));
|
||||
assertThat(getResponse.getField("_parent").getValue().toString(), equalTo("parent_1"));
|
||||
}
|
||||
|
@ -779,16 +760,10 @@ public class GetActionIT extends ESIntegTestCase {
|
|||
" },\n" +
|
||||
" \"mappings\": {\n" +
|
||||
" \"parentdoc\": {\n" +
|
||||
" \"_ttl\": {\n" +
|
||||
" \"enabled\": true\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"doc\": {\n" +
|
||||
" \"_parent\": {\n" +
|
||||
" \"type\": \"parentdoc\"\n" +
|
||||
" },\n" +
|
||||
" \"_ttl\": {\n" +
|
||||
" \"enabled\": true\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
|
@ -798,7 +773,7 @@ public class GetActionIT extends ESIntegTestCase {
|
|||
|
||||
client().prepareIndex("test", "doc").setId("1").setSource("{}").setParent("1").setTTL(TimeValue.timeValueHours(1).getMillis()).get();
|
||||
|
||||
String[] fieldsList = {"_ttl", "_parent"};
|
||||
String[] fieldsList = {"_parent"};
|
||||
// before refresh - document is only in translog
|
||||
assertGetFieldsAlwaysWorks(indexOrAlias(), "doc", "1", fieldsList, "1");
|
||||
refresh();
|
||||
|
@ -814,14 +789,6 @@ public class GetActionIT extends ESIntegTestCase {
|
|||
" \"settings\": {\n" +
|
||||
" \"index.translog.flush_threshold_size\": \"1pb\",\n" +
|
||||
" \"refresh_interval\": \"-1\"\n" +
|
||||
" },\n" +
|
||||
" \"mappings\": {\n" +
|
||||
" \"parentdoc\": {},\n" +
|
||||
" \"doc\": {\n" +
|
||||
" \"_timestamp\": {\n" +
|
||||
" \"enabled\": true\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
|
@ -831,7 +798,7 @@ public class GetActionIT extends ESIntegTestCase {
|
|||
" \"text\": \"some text.\"\n" +
|
||||
"}\n";
|
||||
client().prepareIndex("test", "doc").setId("1").setSource(doc).setRouting("1").get();
|
||||
String[] fieldsList = {"_timestamp", "_routing"};
|
||||
String[] fieldsList = {"_routing"};
|
||||
// before refresh - document is only in translog
|
||||
assertGetFieldsAlwaysWorks(indexOrAlias(), "doc", "1", fieldsList, "1");
|
||||
refresh();
|
||||
|
|
|
@ -40,7 +40,6 @@ import org.elasticsearch.index.mapper.DocumentMapperParser;
|
|||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.index.mapper.ParseContext.Document;
|
||||
import org.elasticsearch.index.mapper.internal.AllFieldMapper;
|
||||
import org.elasticsearch.index.mapper.internal.TimestampFieldMapper;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.test.ESSingleNodeTestCase;
|
||||
import org.elasticsearch.test.InternalSettingsPlugin;
|
||||
|
@ -50,9 +49,7 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.test.StreamsUtils.copyToBytesFromClasspath;
|
||||
|
@ -430,23 +427,6 @@ public class SimpleAllMapperTests extends ESSingleNodeTestCase {
|
|||
parser.parse("test", new CompressedXContent(mapping));
|
||||
}
|
||||
|
||||
// issue https://github.com/elastic/elasticsearch/issues/5864
|
||||
public void testMetadataMappersStillWorking() throws MapperParsingException, IOException {
|
||||
String mapping = "{";
|
||||
Map<String, String> rootTypes = new HashMap<>();
|
||||
//just pick some example from DocumentMapperParser.rootTypeParsers
|
||||
rootTypes.put(TimestampFieldMapper.NAME, "{\"enabled\" : true}");
|
||||
rootTypes.put("include_in_all", "true");
|
||||
rootTypes.put("dynamic_date_formats", "[\"yyyy-MM-dd\", \"dd-MM-yyyy\"]");
|
||||
rootTypes.put("numeric_detection", "true");
|
||||
rootTypes.put("dynamic_templates", "[]");
|
||||
for (String key : rootTypes.keySet()) {
|
||||
mapping += "\"" + key+ "\"" + ":" + rootTypes.get(key) + ",\n";
|
||||
}
|
||||
mapping += "\"properties\":{}}" ;
|
||||
createIndex("test").mapperService().documentMapperParser().parse("test", new CompressedXContent(mapping));
|
||||
}
|
||||
|
||||
public void testDocValuesNotAllowed() throws IOException {
|
||||
String mapping = jsonBuilder().startObject().startObject("type")
|
||||
.startObject("_all")
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.index.mapper.timestamp;
|
|||
import org.apache.lucene.index.IndexOptions;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.TimestampParsingException;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||
import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
||||
|
@ -31,25 +32,31 @@ import org.elasticsearch.common.compress.CompressedXContent;
|
|||
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.joda.Joda;
|
||||
import org.elasticsearch.common.lucene.uid.Versions;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.index.IndexService;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.index.mapper.DocumentMapperParser;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.mapper.ParsedDocument;
|
||||
import org.elasticsearch.index.mapper.SourceToParse;
|
||||
import org.elasticsearch.index.mapper.MapperService.MergeReason;
|
||||
import org.elasticsearch.index.mapper.internal.TimestampFieldMapper;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.test.ESSingleNodeTestCase;
|
||||
import org.elasticsearch.test.InternalSettingsPlugin;
|
||||
import org.elasticsearch.test.VersionUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import static org.elasticsearch.test.StreamsUtils.copyToStringFromClasspath;
|
||||
import static org.elasticsearch.test.VersionUtils.randomVersion;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
@ -58,19 +65,35 @@ import static org.hamcrest.Matchers.instanceOf;
|
|||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.lessThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class TimestampMappingTests extends ESSingleNodeTestCase {
|
||||
|
||||
private static final Settings BW_SETTINGS = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_2_3_0).build();
|
||||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> getPlugins() {
|
||||
return pluginList(InternalSettingsPlugin.class);
|
||||
}
|
||||
|
||||
public void testRejectedOn5x() throws IOException {
|
||||
String mapping = XContentFactory.jsonBuilder().startObject()
|
||||
.startObject("type")
|
||||
.startObject("_timestamp")
|
||||
.field("enabled", true)
|
||||
.endObject()
|
||||
.endObject().endObject().string();
|
||||
IndexService index = createIndex("test");
|
||||
IllegalArgumentException expected = expectThrows(IllegalArgumentException.class,
|
||||
() -> index.mapperService().merge("type", new CompressedXContent(mapping), MergeReason.MAPPING_UPDATE, false));
|
||||
assertThat(expected.getMessage(), startsWith("[_timestamp] is removed"));
|
||||
}
|
||||
|
||||
public void testSimpleDisabled() throws Exception {
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
|
||||
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
DocumentMapper docMapper = createIndex("test", BW_SETTINGS).mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
BytesReference source = XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.field("field", "value")
|
||||
|
@ -85,7 +108,7 @@ public class TimestampMappingTests extends ESSingleNodeTestCase {
|
|||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("_timestamp").field("enabled", "yes").endObject()
|
||||
.endObject().endObject().string();
|
||||
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
DocumentMapper docMapper = createIndex("test", BW_SETTINGS).mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
BytesReference source = XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.field("field", "value")
|
||||
|
@ -99,10 +122,7 @@ public class TimestampMappingTests extends ESSingleNodeTestCase {
|
|||
}
|
||||
|
||||
public void testDefaultValues() throws Exception {
|
||||
Version version;
|
||||
do {
|
||||
version = randomVersion(random());
|
||||
} while (version.before(Version.V_2_0_0_beta1));
|
||||
Version version = VersionUtils.randomVersionBetween(random(), Version.V_2_0_0_beta1, Version.V_5_0_0_alpha3);
|
||||
for (String mapping : Arrays.asList(
|
||||
XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string(),
|
||||
XContentFactory.jsonBuilder().startObject().startObject("type").startObject("_timestamp").endObject().endObject().endObject().string())) {
|
||||
|
@ -120,7 +140,7 @@ public class TimestampMappingTests extends ESSingleNodeTestCase {
|
|||
String enabledMapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("_timestamp").field("enabled", true).endObject()
|
||||
.endObject().endObject().string();
|
||||
MapperService mapperService = createIndex("test").mapperService();
|
||||
MapperService mapperService = createIndex("test", BW_SETTINGS).mapperService();
|
||||
DocumentMapper enabledMapper = mapperService.merge("type", new CompressedXContent(enabledMapping), MapperService.MergeReason.MAPPING_UPDATE, false);
|
||||
|
||||
String disabledMapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
|
@ -146,7 +166,7 @@ public class TimestampMappingTests extends ESSingleNodeTestCase {
|
|||
.field("foo", "bar")
|
||||
.endObject();
|
||||
|
||||
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping.string()));
|
||||
DocumentMapper docMapper = createIndex("test", BW_SETTINGS).mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping.string()));
|
||||
MetaData metaData = client().admin().cluster().prepareState().get().getState().getMetaData();
|
||||
|
||||
MappingMetaData mappingMetaData = new MappingMetaData(docMapper);
|
||||
|
@ -172,7 +192,7 @@ public class TimestampMappingTests extends ESSingleNodeTestCase {
|
|||
.endObject();
|
||||
|
||||
MetaData metaData = MetaData.builder().build();
|
||||
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping.string()));
|
||||
DocumentMapper docMapper = createIndex("test", BW_SETTINGS).mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping.string()));
|
||||
|
||||
MappingMetaData mappingMetaData = new MappingMetaData(docMapper);
|
||||
|
||||
|
@ -195,7 +215,7 @@ public class TimestampMappingTests extends ESSingleNodeTestCase {
|
|||
.endObject()
|
||||
.endObject().endObject();
|
||||
try {
|
||||
createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping.string()));
|
||||
createIndex("test", BW_SETTINGS).mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping.string()));
|
||||
fail("we should reject the mapping with a TimestampParsingException: default timestamp can not be set to null");
|
||||
} catch (TimestampParsingException e) {
|
||||
assertThat(e.getDetailedMessage(), containsString("default timestamp can not be set to null"));
|
||||
|
@ -212,7 +232,7 @@ public class TimestampMappingTests extends ESSingleNodeTestCase {
|
|||
.endObject().endObject();
|
||||
|
||||
try {
|
||||
createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping.string()));
|
||||
createIndex("test", BW_SETTINGS).mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping.string()));
|
||||
fail("we should reject the mapping with a TimestampParsingException: default timestamp can not be set to null");
|
||||
} catch (TimestampParsingException e) {
|
||||
assertThat(e.getDetailedMessage(), containsString("default timestamp can not be set to null"));
|
||||
|
@ -230,7 +250,7 @@ public class TimestampMappingTests extends ESSingleNodeTestCase {
|
|||
.endObject().endObject();
|
||||
|
||||
try {
|
||||
createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping.string()));
|
||||
createIndex("test", BW_SETTINGS).mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping.string()));
|
||||
fail("we should reject the mapping with a TimestampParsingException: default timestamp can not be set with ignore_missing set to false");
|
||||
} catch (TimestampParsingException e) {
|
||||
assertThat(e.getDetailedMessage(), containsString("default timestamp can not be set with ignore_missing set to false"));
|
||||
|
@ -250,7 +270,7 @@ public class TimestampMappingTests extends ESSingleNodeTestCase {
|
|||
.endObject();
|
||||
|
||||
MetaData metaData = MetaData.builder().build();
|
||||
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping.string()));
|
||||
DocumentMapper docMapper = createIndex("test", BW_SETTINGS).mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping.string()));
|
||||
|
||||
MappingMetaData mappingMetaData = new MappingMetaData(docMapper);
|
||||
|
||||
|
@ -323,7 +343,7 @@ public class TimestampMappingTests extends ESSingleNodeTestCase {
|
|||
.field("enabled", true)
|
||||
.field("default", "1970-01-01")
|
||||
.endObject().endObject().endObject().string();
|
||||
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
|
||||
DocumentMapperParser parser = createIndex("test", BW_SETTINGS).mapperService().documentMapperParser();
|
||||
|
||||
DocumentMapper docMapper = parser.parse("type", new CompressedXContent(mapping));
|
||||
docMapper = parser.parse("type", docMapper.mappingSource());
|
||||
|
@ -360,7 +380,7 @@ public class TimestampMappingTests extends ESSingleNodeTestCase {
|
|||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("_timestamp").field("enabled", true).field("default", "1970").field("format", "YYYY").endObject()
|
||||
.endObject().endObject().string();
|
||||
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
DocumentMapper docMapper = createIndex("test", BW_SETTINGS).mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
|
||||
try {
|
||||
docMapper.parse("test", "type", "1", XContentFactory.jsonBuilder()
|
||||
|
@ -375,7 +395,7 @@ public class TimestampMappingTests extends ESSingleNodeTestCase {
|
|||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("_timestamp").field("enabled", true).field("format", "yyyyMMddHH").endObject()
|
||||
.endObject().endObject().string();
|
||||
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
DocumentMapper docMapper = createIndex("test", BW_SETTINGS).mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
MetaData metaData = client().admin().cluster().prepareState().get().getState().getMetaData();
|
||||
|
||||
XContentBuilder doc = XContentFactory.jsonBuilder().startObject().endObject();
|
||||
|
@ -392,7 +412,7 @@ public class TimestampMappingTests extends ESSingleNodeTestCase {
|
|||
.endObject().endObject().string();
|
||||
BytesReference source = XContentFactory.jsonBuilder().startObject().field("field", "value").endObject().bytes();
|
||||
// test with 2.x
|
||||
DocumentMapper currentMapper = createIndex("new-index").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
DocumentMapper currentMapper = createIndex("new-index", BW_SETTINGS).mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
|
||||
// this works with 2.x
|
||||
IndexRequest request = new IndexRequest("new-index", "type", "1").source(source).timestamp("1970-01-01");
|
||||
|
@ -407,4 +427,54 @@ public class TimestampMappingTests extends ESSingleNodeTestCase {
|
|||
assertThat(e.getMessage(), containsString("failed to parse timestamp [1234567890]"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testSizeTimestampIndexParsing() throws IOException {
|
||||
IndexService indexService = createIndex("test", BW_SETTINGS);
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/update/default_mapping_with_disabled_root_types.json");
|
||||
DocumentMapper documentMapper = indexService.mapperService().parse("type", new CompressedXContent(mapping), true);
|
||||
assertThat(documentMapper.mappingSource().string(), equalTo(mapping));
|
||||
documentMapper = indexService.mapperService().parse("type", new CompressedXContent(documentMapper.mappingSource().string()), true);
|
||||
assertThat(documentMapper.mappingSource().string(), equalTo(mapping));
|
||||
}
|
||||
|
||||
public void testDefaultApplied() throws IOException {
|
||||
createIndex("test1", BW_SETTINGS);
|
||||
createIndex("test2", BW_SETTINGS);
|
||||
XContentBuilder defaultMapping = XContentFactory.jsonBuilder().startObject()
|
||||
.startObject(MapperService.DEFAULT_MAPPING).startObject("_timestamp").field("enabled", true).endObject().endObject()
|
||||
.endObject();
|
||||
client().admin().indices().preparePutMapping().setType(MapperService.DEFAULT_MAPPING).setSource(defaultMapping).get();
|
||||
XContentBuilder typeMapping = XContentFactory.jsonBuilder().startObject()
|
||||
.startObject("type").startObject("_all").field("enabled", false).endObject().endObject()
|
||||
.endObject();
|
||||
client().admin().indices().preparePutMapping("test1").setType("type").setSource(typeMapping).get();
|
||||
client().admin().indices().preparePutMapping("test1", "test2").setType("type").setSource(typeMapping).get();
|
||||
|
||||
GetMappingsResponse response = client().admin().indices().prepareGetMappings("test2").get();
|
||||
assertNotNull(response.getMappings().get("test2").get("type").getSourceAsMap().get("_all"));
|
||||
assertFalse((Boolean) ((LinkedHashMap) response.getMappings().get("test2").get("type").getSourceAsMap().get("_all")).get("enabled"));
|
||||
assertNotNull(response.getMappings().get("test2").get("type").getSourceAsMap().get("_timestamp"));
|
||||
assertTrue((Boolean)((LinkedHashMap)response.getMappings().get("test2").get("type").getSourceAsMap().get("_timestamp")).get("enabled"));
|
||||
}
|
||||
|
||||
public void testTimestampParsing() throws IOException {
|
||||
IndexService indexService = createIndex("test", BW_SETTINGS);
|
||||
XContentBuilder indexMapping = XContentFactory.jsonBuilder();
|
||||
boolean enabled = randomBoolean();
|
||||
indexMapping.startObject()
|
||||
.startObject("type")
|
||||
.startObject("_timestamp")
|
||||
.field("enabled", enabled)
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject();
|
||||
DocumentMapper documentMapper = indexService.mapperService().parse("type", new CompressedXContent(indexMapping.string()), true);
|
||||
assertThat(documentMapper.timestampFieldMapper().enabled(), equalTo(enabled));
|
||||
assertTrue(documentMapper.timestampFieldMapper().fieldType().stored());
|
||||
assertTrue(documentMapper.timestampFieldMapper().fieldType().hasDocValues());
|
||||
documentMapper = indexService.mapperService().parse("type", new CompressedXContent(documentMapper.mappingSource().string()), true);
|
||||
assertThat(documentMapper.timestampFieldMapper().enabled(), equalTo(enabled));
|
||||
assertTrue(documentMapper.timestampFieldMapper().fieldType().hasDocValues());
|
||||
assertTrue(documentMapper.timestampFieldMapper().fieldType().stored());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
package org.elasticsearch.index.mapper.ttl;
|
||||
|
||||
import org.apache.lucene.index.IndexOptions;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.compress.CompressedXContent;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
|
@ -30,22 +32,48 @@ import org.elasticsearch.index.IndexService;
|
|||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.mapper.MapperService.MergeReason;
|
||||
import org.elasticsearch.index.mapper.ParsedDocument;
|
||||
import org.elasticsearch.index.mapper.SourceToParse;
|
||||
import org.elasticsearch.index.mapper.internal.TTLFieldMapper;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.test.ESSingleNodeTestCase;
|
||||
import org.elasticsearch.test.InternalSettingsPlugin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
|
||||
public class TTLMappingTests extends ESSingleNodeTestCase {
|
||||
|
||||
private static final Settings BW_SETTINGS = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_2_3_0).build();
|
||||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> getPlugins() {
|
||||
return pluginList(InternalSettingsPlugin.class);
|
||||
}
|
||||
|
||||
public void testRejectedOn5x() throws IOException {
|
||||
String mapping = XContentFactory.jsonBuilder().startObject()
|
||||
.startObject("type")
|
||||
.startObject("_ttl")
|
||||
.field("enabled", true)
|
||||
.endObject()
|
||||
.endObject().endObject().string();
|
||||
IndexService index = createIndex("test");
|
||||
IllegalArgumentException expected = expectThrows(IllegalArgumentException.class,
|
||||
() -> index.mapperService().merge("type", new CompressedXContent(mapping), MergeReason.MAPPING_UPDATE, false));
|
||||
assertThat(expected.getMessage(), startsWith("[_ttl] is removed"));
|
||||
}
|
||||
|
||||
public void testSimpleDisabled() throws Exception {
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
|
||||
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
DocumentMapper docMapper = createIndex("test", BW_SETTINGS).mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
BytesReference source = XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.field("field", "value")
|
||||
|
@ -60,7 +88,7 @@ public class TTLMappingTests extends ESSingleNodeTestCase {
|
|||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("_ttl").field("enabled", "yes").endObject()
|
||||
.endObject().endObject().string();
|
||||
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
DocumentMapper docMapper = createIndex("test", BW_SETTINGS).mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
BytesReference source = XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.field("field", "value")
|
||||
|
@ -75,7 +103,7 @@ public class TTLMappingTests extends ESSingleNodeTestCase {
|
|||
|
||||
public void testDefaultValues() throws Exception {
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string();
|
||||
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
DocumentMapper docMapper = createIndex("test", BW_SETTINGS).mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
assertThat(docMapper.TTLFieldMapper().enabled(), equalTo(TTLFieldMapper.Defaults.ENABLED_STATE.enabled));
|
||||
assertThat(docMapper.TTLFieldMapper().fieldType().stored(), equalTo(TTLFieldMapper.Defaults.TTL_FIELD_TYPE.stored()));
|
||||
assertThat(docMapper.TTLFieldMapper().fieldType().indexOptions(), equalTo(TTLFieldMapper.Defaults.TTL_FIELD_TYPE.indexOptions()));
|
||||
|
@ -93,7 +121,7 @@ public class TTLMappingTests extends ESSingleNodeTestCase {
|
|||
.startObject("properties").field("field").startObject().field("type", "text").endObject().endObject()
|
||||
.endObject().endObject().string();
|
||||
|
||||
MapperService mapperService = createIndex("test").mapperService();
|
||||
MapperService mapperService = createIndex("test", BW_SETTINGS).mapperService();
|
||||
DocumentMapper mapperWithoutTtl = mapperService.merge("type", new CompressedXContent(mappingWithoutTtl), MapperService.MergeReason.MAPPING_UPDATE, false);
|
||||
DocumentMapper mapperWithTtl = mapperService.merge("type", new CompressedXContent(mappingWithTtl), MapperService.MergeReason.MAPPING_UPDATE, false);
|
||||
|
||||
|
@ -116,7 +144,7 @@ public class TTLMappingTests extends ESSingleNodeTestCase {
|
|||
.startObject("properties").field("field").startObject().field("type", "text").endObject().endObject()
|
||||
.endObject().endObject().string();
|
||||
|
||||
MapperService mapperService = createIndex("test").mapperService();
|
||||
MapperService mapperService = createIndex("test", BW_SETTINGS).mapperService();
|
||||
DocumentMapper initialMapper = mapperService.merge("type", new CompressedXContent(mappingWithTtl), MapperService.MergeReason.MAPPING_UPDATE, false);
|
||||
DocumentMapper updatedMapper = mapperService.merge("type", new CompressedXContent(updatedMapping), MapperService.MergeReason.MAPPING_UPDATE, false);
|
||||
|
||||
|
@ -127,7 +155,7 @@ public class TTLMappingTests extends ESSingleNodeTestCase {
|
|||
public void testThatDisablingTTLReportsConflict() throws Exception {
|
||||
String mappingWithTtl = getMappingWithTtlEnabled().string();
|
||||
String mappingWithTtlDisabled = getMappingWithTtlDisabled().string();
|
||||
MapperService mapperService = createIndex("test").mapperService();
|
||||
MapperService mapperService = createIndex("test", BW_SETTINGS).mapperService();
|
||||
DocumentMapper initialMapper = mapperService.merge("type", new CompressedXContent(mappingWithTtl), MapperService.MergeReason.MAPPING_UPDATE, false);
|
||||
|
||||
try {
|
||||
|
@ -143,7 +171,7 @@ public class TTLMappingTests extends ESSingleNodeTestCase {
|
|||
public void testThatDisablingTTLReportsConflictOnCluster() throws Exception {
|
||||
String mappingWithTtl = getMappingWithTtlEnabled().string();
|
||||
String mappingWithTtlDisabled = getMappingWithTtlDisabled().string();
|
||||
assertAcked(client().admin().indices().prepareCreate("testindex").addMapping("type", mappingWithTtl));
|
||||
assertAcked(client().admin().indices().prepareCreate("testindex").setSettings(BW_SETTINGS).addMapping("type", mappingWithTtl));
|
||||
GetMappingsResponse mappingsBeforeUpdateResponse = client().admin().indices().prepareGetMappings("testindex").addTypes("type").get();
|
||||
try {
|
||||
client().admin().indices().preparePutMapping("testindex").setSource(mappingWithTtlDisabled).setType("type").get();
|
||||
|
@ -158,7 +186,7 @@ public class TTLMappingTests extends ESSingleNodeTestCase {
|
|||
public void testThatEnablingTTLAfterFirstDisablingWorks() throws Exception {
|
||||
String mappingWithTtl = getMappingWithTtlEnabled().string();
|
||||
String withTtlDisabled = getMappingWithTtlDisabled().string();
|
||||
assertAcked(client().admin().indices().prepareCreate("testindex").addMapping("type", withTtlDisabled));
|
||||
assertAcked(client().admin().indices().prepareCreate("testindex").setSettings(BW_SETTINGS).addMapping("type", withTtlDisabled));
|
||||
GetMappingsResponse mappingsAfterUpdateResponse = client().admin().indices().prepareGetMappings("testindex").addTypes("type").get();
|
||||
assertThat(mappingsAfterUpdateResponse.getMappings().get("testindex").get("type").sourceAsMap().get("_ttl").toString(), equalTo("{enabled=false}"));
|
||||
client().admin().indices().preparePutMapping("testindex").setSource(mappingWithTtl).setType("type").get();
|
||||
|
@ -167,20 +195,20 @@ public class TTLMappingTests extends ESSingleNodeTestCase {
|
|||
}
|
||||
|
||||
public void testNoConflictIfNothingSetAndDisabledLater() throws Exception {
|
||||
IndexService indexService = createIndex("testindex", Settings.builder().build(), "type");
|
||||
IndexService indexService = createIndex("testindex", BW_SETTINGS, "type");
|
||||
XContentBuilder mappingWithTtlDisabled = getMappingWithTtlDisabled("7d");
|
||||
indexService.mapperService().merge("type", new CompressedXContent(mappingWithTtlDisabled.string()), MapperService.MergeReason.MAPPING_UPDATE, false);
|
||||
}
|
||||
|
||||
public void testNoConflictIfNothingSetAndEnabledLater() throws Exception {
|
||||
IndexService indexService = createIndex("testindex", Settings.builder().build(), "type");
|
||||
IndexService indexService = createIndex("testindex", BW_SETTINGS, "type");
|
||||
XContentBuilder mappingWithTtlEnabled = getMappingWithTtlEnabled("7d");
|
||||
indexService.mapperService().merge("type", new CompressedXContent(mappingWithTtlEnabled.string()), MapperService.MergeReason.MAPPING_UPDATE, false);
|
||||
}
|
||||
|
||||
public void testMergeWithOnlyDefaultSet() throws Exception {
|
||||
XContentBuilder mappingWithTtlEnabled = getMappingWithTtlEnabled("7d");
|
||||
IndexService indexService = createIndex("testindex", Settings.builder().build(), "type", mappingWithTtlEnabled);
|
||||
IndexService indexService = createIndex("testindex", BW_SETTINGS, "type", mappingWithTtlEnabled);
|
||||
XContentBuilder mappingWithOnlyDefaultSet = getMappingWithOnlyTtlDefaultSet("6m");
|
||||
indexService.mapperService().merge("type", new CompressedXContent(mappingWithOnlyDefaultSet.string()), MapperService.MergeReason.MAPPING_UPDATE, false);
|
||||
CompressedXContent mappingAfterMerge = indexService.mapperService().documentMapper("type").mappingSource();
|
||||
|
@ -189,7 +217,7 @@ public class TTLMappingTests extends ESSingleNodeTestCase {
|
|||
|
||||
public void testMergeWithOnlyDefaultSetTtlDisabled() throws Exception {
|
||||
XContentBuilder mappingWithTtlEnabled = getMappingWithTtlDisabled("7d");
|
||||
IndexService indexService = createIndex("testindex", Settings.builder().build(), "type", mappingWithTtlEnabled);
|
||||
IndexService indexService = createIndex("testindex", BW_SETTINGS, "type", mappingWithTtlEnabled);
|
||||
CompressedXContent mappingAfterCreation = indexService.mapperService().documentMapper("type").mappingSource();
|
||||
assertThat(mappingAfterCreation, equalTo(new CompressedXContent("{\"type\":{\"_ttl\":{\"enabled\":false},\"properties\":{\"field\":{\"type\":\"text\"}}}}")));
|
||||
XContentBuilder mappingWithOnlyDefaultSet = getMappingWithOnlyTtlDefaultSet("6m");
|
||||
|
@ -202,7 +230,7 @@ public class TTLMappingTests extends ESSingleNodeTestCase {
|
|||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("_ttl").field("enabled", true).endObject()
|
||||
.endObject().endObject().string();
|
||||
DocumentMapper docMapper = createIndex("test").mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
DocumentMapper docMapper = createIndex("test", BW_SETTINGS).mapperService().documentMapperParser().parse("type", new CompressedXContent(mapping));
|
||||
|
||||
try {
|
||||
docMapper.parse("test", "type", "1", XContentFactory.jsonBuilder()
|
||||
|
|
|
@ -31,12 +31,12 @@ import static org.hamcrest.Matchers.equalTo;
|
|||
public class ParseMappingTypeLevelTests extends ESSingleNodeTestCase {
|
||||
public void testTypeLevel() throws Exception {
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("_timestamp").field("enabled", true).endObject()
|
||||
.startObject("_all").field("enabled", false).endObject()
|
||||
.endObject().endObject().string();
|
||||
|
||||
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
|
||||
DocumentMapper mapper = parser.parse("type", new CompressedXContent(mapping));
|
||||
assertThat(mapper.type(), equalTo("type"));
|
||||
assertThat(mapper.timestampFieldMapper().enabled(), equalTo(true));
|
||||
assertThat(mapper.allFieldMapper().enabled(), equalTo(false));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,16 +139,6 @@ public class UpdateMappingOnClusterIT extends ESIntegTestCase {
|
|||
compareMappingOnNodes(mappingsBeforeUpdateResponse);
|
||||
}
|
||||
|
||||
// checks if the setting for timestamp and size are kept even if disabled
|
||||
public void testDisabledSizeTimestampIndexDoNotLooseMappings() throws Exception {
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/update/default_mapping_with_disabled_root_types.json");
|
||||
prepareCreate(INDEX).addMapping(TYPE, mapping).get();
|
||||
GetMappingsResponse mappingsBeforeGreen = client().admin().indices().prepareGetMappings(INDEX).addTypes(TYPE).get();
|
||||
ensureGreen(INDEX);
|
||||
// make sure all nodes have same cluster state
|
||||
compareMappingOnNodes(mappingsBeforeGreen);
|
||||
}
|
||||
|
||||
protected void testConflict(String mapping, String mappingUpdate, String... errorMessages) throws InterruptedException {
|
||||
assertAcked(prepareCreate(INDEX).setSource(mapping).get());
|
||||
ensureGreen(INDEX);
|
||||
|
|
|
@ -259,56 +259,6 @@ public class UpdateMappingTests extends ESSingleNodeTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testTimestampParsing() throws IOException {
|
||||
IndexService indexService = createIndex("test");
|
||||
XContentBuilder indexMapping = XContentFactory.jsonBuilder();
|
||||
boolean enabled = randomBoolean();
|
||||
indexMapping.startObject()
|
||||
.startObject("type")
|
||||
.startObject("_timestamp")
|
||||
.field("enabled", enabled)
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject();
|
||||
DocumentMapper documentMapper = indexService.mapperService().parse("type", new CompressedXContent(indexMapping.string()), true);
|
||||
assertThat(documentMapper.timestampFieldMapper().enabled(), equalTo(enabled));
|
||||
assertTrue(documentMapper.timestampFieldMapper().fieldType().stored());
|
||||
assertTrue(documentMapper.timestampFieldMapper().fieldType().hasDocValues());
|
||||
documentMapper = indexService.mapperService().parse("type", new CompressedXContent(documentMapper.mappingSource().string()), true);
|
||||
assertThat(documentMapper.timestampFieldMapper().enabled(), equalTo(enabled));
|
||||
assertTrue(documentMapper.timestampFieldMapper().fieldType().hasDocValues());
|
||||
assertTrue(documentMapper.timestampFieldMapper().fieldType().stored());
|
||||
}
|
||||
|
||||
public void testSizeTimestampIndexParsing() throws IOException {
|
||||
IndexService indexService = createIndex("test", Settings.builder().build());
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/update/default_mapping_with_disabled_root_types.json");
|
||||
DocumentMapper documentMapper = indexService.mapperService().parse("type", new CompressedXContent(mapping), true);
|
||||
assertThat(documentMapper.mappingSource().string(), equalTo(mapping));
|
||||
documentMapper = indexService.mapperService().parse("type", new CompressedXContent(documentMapper.mappingSource().string()), true);
|
||||
assertThat(documentMapper.mappingSource().string(), equalTo(mapping));
|
||||
}
|
||||
|
||||
public void testDefaultApplied() throws IOException {
|
||||
createIndex("test1", Settings.builder().build());
|
||||
createIndex("test2", Settings.builder().build());
|
||||
XContentBuilder defaultMapping = XContentFactory.jsonBuilder().startObject()
|
||||
.startObject(MapperService.DEFAULT_MAPPING).startObject("_timestamp").field("enabled", true).endObject().endObject()
|
||||
.endObject();
|
||||
client().admin().indices().preparePutMapping().setType(MapperService.DEFAULT_MAPPING).setSource(defaultMapping).get();
|
||||
XContentBuilder typeMapping = XContentFactory.jsonBuilder().startObject()
|
||||
.startObject("type").startObject("_all").field("enabled", false).endObject().endObject()
|
||||
.endObject();
|
||||
client().admin().indices().preparePutMapping("test1").setType("type").setSource(typeMapping).get();
|
||||
client().admin().indices().preparePutMapping("test1", "test2").setType("type").setSource(typeMapping).get();
|
||||
|
||||
GetMappingsResponse response = client().admin().indices().prepareGetMappings("test2").get();
|
||||
assertNotNull(response.getMappings().get("test2").get("type").getSourceAsMap().get("_all"));
|
||||
assertFalse((Boolean) ((LinkedHashMap) response.getMappings().get("test2").get("type").getSourceAsMap().get("_all")).get("enabled"));
|
||||
assertNotNull(response.getMappings().get("test2").get("type").getSourceAsMap().get("_timestamp"));
|
||||
assertTrue((Boolean)((LinkedHashMap)response.getMappings().get("test2").get("type").getSourceAsMap().get("_timestamp")).get("enabled"));
|
||||
}
|
||||
|
||||
public void testRejectFieldDefinedTwice() throws IOException {
|
||||
String mapping1 = XContentFactory.jsonBuilder().startObject()
|
||||
.startObject("type1")
|
||||
|
|
|
@ -65,7 +65,6 @@ import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSear
|
|||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.core.IsNull.notNullValue;
|
||||
|
||||
|
@ -107,8 +106,7 @@ public class DateHistogramIT extends ESIntegTestCase {
|
|||
|
||||
@Override
|
||||
public void setupSuiteScopeCluster() throws Exception {
|
||||
assertAcked(prepareCreate("idx").addMapping("type", "_timestamp", "enabled=true"));
|
||||
createIndex("idx_unmapped");
|
||||
createIndex("idx", "idx_unmapped");
|
||||
// TODO: would be nice to have more random data here
|
||||
assertAcked(prepareCreate("empty_bucket_idx").addMapping("type", "value", "type=integer"));
|
||||
List<IndexRequestBuilder> builders = new ArrayList<>();
|
||||
|
@ -1141,13 +1139,6 @@ public class DateHistogramIT extends ESIntegTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testTimestampField() { // see #11692
|
||||
SearchResponse response = client().prepareSearch("idx").addAggregation(dateHistogram("histo").field("_timestamp").dateHistogramInterval(randomFrom(DateHistogramInterval.DAY, DateHistogramInterval.MONTH))).get();
|
||||
assertSearchResponse(response);
|
||||
Histogram histo = response.getAggregations().get("histo");
|
||||
assertThat(histo.getBuckets().size(), greaterThan(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* When DST ends, local time turns back one hour, so between 2am and 4am wall time we should have four buckets:
|
||||
* "2015-10-25T02:00:00.000+02:00",
|
||||
|
|
|
@ -36,7 +36,6 @@ import org.elasticsearch.index.query.QueryBuilders;
|
|||
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
import org.elasticsearch.search.SearchHitField;
|
||||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
import org.elasticsearch.test.InternalSettingsPlugin;
|
||||
import org.hamcrest.Matchers;
|
||||
|
@ -70,10 +69,8 @@ import static org.hamcrest.Matchers.closeTo;
|
|||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.lessThan;
|
||||
import static org.hamcrest.Matchers.lessThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
|
||||
|
@ -1340,16 +1337,12 @@ public class FieldSortIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void testSortMetaField() throws Exception {
|
||||
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("_timestamp").field("enabled", true).endObject()
|
||||
.endObject().endObject();
|
||||
assertAcked(prepareCreate("test")
|
||||
.addMapping("type", mapping));
|
||||
createIndex("test");
|
||||
ensureGreen();
|
||||
final int numDocs = randomIntBetween(10, 20);
|
||||
IndexRequestBuilder[] indexReqs = new IndexRequestBuilder[numDocs];
|
||||
for (int i = 0; i < numDocs; ++i) {
|
||||
indexReqs[i] = client().prepareIndex("test", "type", Integer.toString(i)).setTimestamp(Integer.toString(randomInt(1000)))
|
||||
indexReqs[i] = client().prepareIndex("test", "type", Integer.toString(i))
|
||||
.setSource();
|
||||
}
|
||||
indexRandom(true, indexReqs);
|
||||
|
@ -1368,37 +1361,6 @@ public class FieldSortIT extends ESIntegTestCase {
|
|||
assertThat(previous, order == SortOrder.ASC ? lessThan(uid) : greaterThan(uid));
|
||||
previous = uid;
|
||||
}
|
||||
|
||||
/*
|
||||
searchResponse = client().prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
.setSize(randomIntBetween(1, numDocs + 5))
|
||||
.addSort("_id", order)
|
||||
.execute().actionGet();
|
||||
assertNoFailures(searchResponse);
|
||||
hits = searchResponse.getHits().hits();
|
||||
previous = order == SortOrder.ASC ? new BytesRef() : UnicodeUtil.BIG_TERM;
|
||||
for (int i = 0; i < hits.length; ++i) {
|
||||
final BytesRef id = new BytesRef(Uid.createUid(hits[i].type(), hits[i].id()));
|
||||
assertThat(previous, order == SortOrder.ASC ? lessThan(id) : greaterThan(id));
|
||||
previous = id;
|
||||
}*/
|
||||
|
||||
searchResponse = client().prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
.setSize(randomIntBetween(1, numDocs + 5))
|
||||
.addSort("_timestamp", order)
|
||||
.addField("_timestamp")
|
||||
.execute().actionGet();
|
||||
assertNoFailures(searchResponse);
|
||||
hits = searchResponse.getHits().hits();
|
||||
Long previousTs = order == SortOrder.ASC ? 0 : Long.MAX_VALUE;
|
||||
for (int i = 0; i < hits.length; ++i) {
|
||||
SearchHitField timestampField = hits[i].getFields().get("_timestamp");
|
||||
Long timestamp = timestampField.<Long>getValue();
|
||||
assertThat(previousTs, order == SortOrder.ASC ? lessThanOrEqualTo(timestamp) : greaterThanOrEqualTo(timestamp));
|
||||
previousTs = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,14 +19,20 @@
|
|||
|
||||
package org.elasticsearch.timestamp;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
|
||||
import org.elasticsearch.action.get.GetResponse;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
||||
import org.elasticsearch.common.Priority;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
import org.elasticsearch.test.InternalSettingsPlugin;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
|
||||
|
@ -41,8 +47,17 @@ import static org.hamcrest.Matchers.notNullValue;
|
|||
/**
|
||||
*/
|
||||
public class SimpleTimestampIT extends ESIntegTestCase {
|
||||
|
||||
private static final Settings BW_SETTINGS = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_2_3_0).build();
|
||||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> nodePlugins() {
|
||||
return pluginList(InternalSettingsPlugin.class);
|
||||
}
|
||||
|
||||
public void testSimpleTimestamp() throws Exception {
|
||||
client().admin().indices().prepareCreate("test")
|
||||
.setSettings(BW_SETTINGS)
|
||||
.addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("_timestamp").field("enabled", true).endObject().endObject().endObject())
|
||||
.execute().actionGet();
|
||||
client().admin().cluster().prepareHealth().setWaitForEvents(Priority.LANGUID).setWaitForGreenStatus().execute().actionGet();
|
||||
|
@ -98,7 +113,7 @@ public class SimpleTimestampIT extends ESIntegTestCase {
|
|||
String type = "mytype";
|
||||
|
||||
XContentBuilder builder = jsonBuilder().startObject().startObject("_timestamp").field("enabled", true).endObject().endObject();
|
||||
assertAcked(client().admin().indices().prepareCreate(index).addMapping(type, builder));
|
||||
assertAcked(client().admin().indices().prepareCreate(index).setSettings(BW_SETTINGS).addMapping(type, builder));
|
||||
|
||||
// check mapping again
|
||||
assertTimestampMappingEnabled(index, type, true);
|
||||
|
@ -117,7 +132,7 @@ public class SimpleTimestampIT extends ESIntegTestCase {
|
|||
String type = "mytype";
|
||||
|
||||
XContentBuilder builder = jsonBuilder().startObject().startObject("_timestamp").field("enabled", true).endObject().endObject();
|
||||
assertAcked(client().admin().indices().prepareCreate(index).addMapping(type, builder));
|
||||
assertAcked(client().admin().indices().prepareCreate(index).setSettings(BW_SETTINGS).addMapping(type, builder));
|
||||
|
||||
// check mapping again
|
||||
assertTimestampMappingEnabled(index, type, true);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.elasticsearch.ttl;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
|
||||
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
|
||||
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
|
||||
|
@ -26,14 +27,19 @@ import org.elasticsearch.action.get.GetResponse;
|
|||
import org.elasticsearch.action.index.IndexResponse;
|
||||
import org.elasticsearch.action.update.UpdateRequestBuilder;
|
||||
import org.elasticsearch.action.update.UpdateResponse;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
import org.elasticsearch.test.InternalSettingsPlugin;
|
||||
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
|
||||
import org.elasticsearch.test.ESIntegTestCase.Scope;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -60,6 +66,11 @@ public class SimpleTTLIT extends ESIntegTestCase {
|
|||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> nodePlugins() {
|
||||
return Collections.singleton(InternalSettingsPlugin.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Settings nodeSettings(int nodeOrdinal) {
|
||||
return Settings.builder()
|
||||
|
@ -70,6 +81,7 @@ public class SimpleTTLIT extends ESIntegTestCase {
|
|||
|
||||
public void testSimpleTTL() throws Exception {
|
||||
assertAcked(prepareCreate("test")
|
||||
.setSettings(IndexMetaData.SETTING_VERSION_CREATED, Version.V_2_3_0.id)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("type1")
|
||||
|
@ -209,7 +221,7 @@ public class SimpleTTLIT extends ESIntegTestCase {
|
|||
String type = "mytype";
|
||||
|
||||
XContentBuilder builder = jsonBuilder().startObject().startObject("_ttl").field("enabled", true).endObject().endObject();
|
||||
assertAcked(client().admin().indices().prepareCreate(index).addMapping(type, builder));
|
||||
assertAcked(client().admin().indices().prepareCreate(index).setSettings(IndexMetaData.SETTING_VERSION_CREATED, Version.V_2_3_0.id).addMapping(type, builder));
|
||||
|
||||
// check mapping again
|
||||
assertTTLMappingEnabled(index, type);
|
||||
|
@ -232,6 +244,7 @@ public class SimpleTTLIT extends ESIntegTestCase {
|
|||
*/
|
||||
public void testNoopUpdate() throws IOException {
|
||||
assertAcked(prepareCreate("test")
|
||||
.setSettings(IndexMetaData.SETTING_VERSION_CREATED, Version.V_2_3_0.id)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("type1")
|
||||
|
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* 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.update;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.admin.indices.alias.Alias;
|
||||
import org.elasticsearch.action.get.GetResponse;
|
||||
import org.elasticsearch.action.index.IndexRequestBuilder;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.action.update.UpdateResponse;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.index.engine.DocumentMissingException;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
import org.elasticsearch.search.SearchHitField;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
import org.elasticsearch.test.InternalSettingsPlugin;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.lessThanOrEqualTo;
|
||||
|
||||
public class TimestampTTLBWIT extends ESIntegTestCase {
|
||||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> nodePlugins() {
|
||||
return Arrays.asList(
|
||||
UpdateIT.FieldIncrementScriptPlugin.class,
|
||||
UpdateIT.ExtractContextInSourceScriptPlugin.class,
|
||||
UpdateIT.PutFieldValuesScriptPlugin.class,
|
||||
InternalSettingsPlugin.class
|
||||
);
|
||||
}
|
||||
|
||||
public void testSort() throws Exception {
|
||||
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||
.startObject("_timestamp").field("enabled", true).endObject()
|
||||
.endObject().endObject();
|
||||
assertAcked(prepareCreate("test")
|
||||
.setSettings(IndexMetaData.SETTING_VERSION_CREATED, Version.V_2_3_0.id)
|
||||
.addMapping("type", mapping));
|
||||
ensureGreen();
|
||||
final int numDocs = randomIntBetween(10, 20);
|
||||
IndexRequestBuilder[] indexReqs = new IndexRequestBuilder[numDocs];
|
||||
for (int i = 0; i < numDocs; ++i) {
|
||||
indexReqs[i] = client().prepareIndex("test", "type", Integer.toString(i)).setTimestamp(Integer.toString(randomInt(1000)))
|
||||
.setSource();
|
||||
}
|
||||
indexRandom(true, indexReqs);
|
||||
|
||||
SortOrder order = randomFrom(SortOrder.values());
|
||||
|
||||
SearchResponse searchResponse = client().prepareSearch()
|
||||
.setQuery(matchAllQuery())
|
||||
.setSize(randomIntBetween(1, numDocs + 5))
|
||||
.addSort("_timestamp", order)
|
||||
.addField("_timestamp")
|
||||
.execute().actionGet();
|
||||
assertNoFailures(searchResponse);
|
||||
SearchHit[] hits = searchResponse.getHits().hits();
|
||||
Long previousTs = order == SortOrder.ASC ? 0 : Long.MAX_VALUE;
|
||||
for (int i = 0; i < hits.length; ++i) {
|
||||
SearchHitField timestampField = hits[i].getFields().get("_timestamp");
|
||||
Long timestamp = timestampField.<Long>getValue();
|
||||
assertThat(previousTs, order == SortOrder.ASC ? lessThanOrEqualTo(timestamp) : greaterThanOrEqualTo(timestamp));
|
||||
previousTs = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
public void testUpdate() throws Exception {
|
||||
assertAcked(prepareCreate("test").addAlias(new Alias("alias"))
|
||||
.setSettings(IndexMetaData.SETTING_VERSION_CREATED, Version.V_2_3_0.id)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("type1")
|
||||
.startObject("_timestamp").field("enabled", true).endObject()
|
||||
.startObject("_ttl").field("enabled", true).endObject()
|
||||
.endObject()
|
||||
.endObject()));
|
||||
|
||||
ensureGreen();
|
||||
|
||||
try {
|
||||
client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
.setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", null)).execute().actionGet();
|
||||
fail();
|
||||
} catch (DocumentMissingException e) {
|
||||
// all is well
|
||||
}
|
||||
|
||||
// check TTL is kept after an update without TTL
|
||||
client().prepareIndex("test", "type1", "2").setSource("field", 1).setTTL(86400000L).setRefreshPolicy(IMMEDIATE).get();
|
||||
GetResponse getResponse = client().prepareGet("test", "type1", "2").setFields("_ttl").execute().actionGet();
|
||||
long ttl = ((Number) getResponse.getField("_ttl").getValue()).longValue();
|
||||
assertThat(ttl, greaterThan(0L));
|
||||
client().prepareUpdate(indexOrAlias(), "type1", "2")
|
||||
.setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", null)).execute().actionGet();
|
||||
getResponse = client().prepareGet("test", "type1", "2").setFields("_ttl").execute().actionGet();
|
||||
ttl = ((Number) getResponse.getField("_ttl").getValue()).longValue();
|
||||
assertThat(ttl, greaterThan(0L));
|
||||
|
||||
// check TTL update
|
||||
client().prepareUpdate(indexOrAlias(), "type1", "2")
|
||||
.setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values",
|
||||
Collections.singletonMap("_ctx", Collections.singletonMap("_ttl", 3600000)))).execute().actionGet();
|
||||
getResponse = client().prepareGet("test", "type1", "2").setFields("_ttl").execute().actionGet();
|
||||
ttl = ((Number) getResponse.getField("_ttl").getValue()).longValue();
|
||||
assertThat(ttl, greaterThan(0L));
|
||||
assertThat(ttl, lessThanOrEqualTo(3600000L));
|
||||
|
||||
// check timestamp update
|
||||
client().prepareIndex("test", "type1", "3").setSource("field", 1).setRefreshPolicy(IMMEDIATE).get();
|
||||
client().prepareUpdate(indexOrAlias(), "type1", "3")
|
||||
.setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values",
|
||||
Collections.singletonMap("_ctx", Collections.singletonMap("_timestamp", "2009-11-15T14:12:12")))).execute()
|
||||
.actionGet();
|
||||
getResponse = client().prepareGet("test", "type1", "3").setFields("_timestamp").execute().actionGet();
|
||||
long timestamp = ((Number) getResponse.getField("_timestamp").getValue()).longValue();
|
||||
assertThat(timestamp, equalTo(1258294332000L));
|
||||
}
|
||||
|
||||
public void testContextVariables() throws Exception {
|
||||
assertAcked(prepareCreate("test").addAlias(new Alias("alias"))
|
||||
.setSettings(IndexMetaData.SETTING_VERSION_CREATED, Version.V_2_3_0.id)
|
||||
.addMapping("type1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("type1")
|
||||
.startObject("_timestamp").field("enabled", true).endObject()
|
||||
.startObject("_ttl").field("enabled", true).endObject()
|
||||
.endObject()
|
||||
.endObject())
|
||||
.addMapping("subtype1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("subtype1")
|
||||
.startObject("_parent").field("type", "type1").endObject()
|
||||
.startObject("_timestamp").field("enabled", true).endObject()
|
||||
.startObject("_ttl").field("enabled", true).endObject()
|
||||
.endObject()
|
||||
.endObject())
|
||||
);
|
||||
ensureGreen();
|
||||
|
||||
// Index some documents
|
||||
long timestamp = System.currentTimeMillis();
|
||||
client().prepareIndex()
|
||||
.setIndex("test")
|
||||
.setType("type1")
|
||||
.setId("parentId1")
|
||||
.setTimestamp(String.valueOf(timestamp-1))
|
||||
.setSource("field1", 0, "content", "bar")
|
||||
.execute().actionGet();
|
||||
|
||||
long ttl = 10000;
|
||||
client().prepareIndex()
|
||||
.setIndex("test")
|
||||
.setType("subtype1")
|
||||
.setId("id1")
|
||||
.setParent("parentId1")
|
||||
.setRouting("routing1")
|
||||
.setTimestamp(String.valueOf(timestamp))
|
||||
.setTTL(ttl)
|
||||
.setSource("field1", 1, "content", "foo")
|
||||
.execute().actionGet();
|
||||
|
||||
// Update the first object and note context variables values
|
||||
UpdateResponse updateResponse = client().prepareUpdate("test", "subtype1", "id1")
|
||||
.setRouting("routing1")
|
||||
.setScript(new Script("", ScriptService.ScriptType.INLINE, "extract_ctx", null))
|
||||
.execute().actionGet();
|
||||
|
||||
assertEquals(2, updateResponse.getVersion());
|
||||
|
||||
GetResponse getResponse = client().prepareGet("test", "subtype1", "id1").setRouting("routing1").execute().actionGet();
|
||||
Map<String, Object> updateContext = (Map<String, Object>) getResponse.getSourceAsMap().get("update_context");
|
||||
assertEquals("test", updateContext.get("_index"));
|
||||
assertEquals("subtype1", updateContext.get("_type"));
|
||||
assertEquals("id1", updateContext.get("_id"));
|
||||
assertEquals(1, updateContext.get("_version"));
|
||||
assertEquals("parentId1", updateContext.get("_parent"));
|
||||
assertEquals("routing1", updateContext.get("_routing"));
|
||||
assertThat(((Integer) updateContext.get("_ttl")).longValue(), allOf(greaterThanOrEqualTo(ttl-3000), lessThanOrEqualTo(ttl)));
|
||||
|
||||
// Idem with the second object
|
||||
updateResponse = client().prepareUpdate("test", "type1", "parentId1")
|
||||
.setScript(new Script("", ScriptService.ScriptType.INLINE, "extract_ctx", null))
|
||||
.execute().actionGet();
|
||||
|
||||
assertEquals(2, updateResponse.getVersion());
|
||||
|
||||
getResponse = client().prepareGet("test", "type1", "parentId1").execute().actionGet();
|
||||
updateContext = (Map<String, Object>) getResponse.getSourceAsMap().get("update_context");
|
||||
assertEquals("test", updateContext.get("_index"));
|
||||
assertEquals("type1", updateContext.get("_type"));
|
||||
assertEquals("parentId1", updateContext.get("_id"));
|
||||
assertEquals(1, updateContext.get("_version"));
|
||||
assertNull(updateContext.get("_parent"));
|
||||
assertNull(updateContext.get("_routing"));
|
||||
assertNull(updateContext.get("_ttl"));
|
||||
}
|
||||
|
||||
private static String indexOrAlias() {
|
||||
return randomBoolean() ? "test" : "alias";
|
||||
}
|
||||
}
|
|
@ -62,14 +62,12 @@ import java.util.concurrent.CountDownLatch;
|
|||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertThrows;
|
||||
import static org.hamcrest.Matchers.allOf;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.lessThanOrEqualTo;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
@ -357,21 +355,14 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
FieldIncrementScriptPlugin.class,
|
||||
ScriptedUpsertScriptPlugin.class,
|
||||
ExtractContextInSourceScriptPlugin.class,
|
||||
InternalSettingsPlugin.class // uses index.merge.enabled
|
||||
InternalSettingsPlugin.class
|
||||
);
|
||||
}
|
||||
|
||||
private void createTestIndex() throws Exception {
|
||||
logger.info("--> creating index test");
|
||||
|
||||
assertAcked(prepareCreate("test").addAlias(new Alias("alias"))
|
||||
.addMapping("type1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("type1")
|
||||
.startObject("_timestamp").field("enabled", true).endObject()
|
||||
.startObject("_ttl").field("enabled", true).endObject()
|
||||
.endObject()
|
||||
.endObject()));
|
||||
assertAcked(prepareCreate("test").addAlias(new Alias("alias")));
|
||||
}
|
||||
|
||||
public void testUpsert() throws Exception {
|
||||
|
@ -638,34 +629,6 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
assertThat(getResponse.isExists(), equalTo(false));
|
||||
}
|
||||
|
||||
// check TTL is kept after an update without TTL
|
||||
client().prepareIndex("test", "type1", "2").setSource("field", 1).setTTL(86400000L).setRefreshPolicy(IMMEDIATE).get();
|
||||
GetResponse getResponse = client().prepareGet("test", "type1", "2").setFields("_ttl").execute().actionGet();
|
||||
long ttl = ((Number) getResponse.getField("_ttl").getValue()).longValue();
|
||||
assertThat(ttl, greaterThan(0L));
|
||||
client().prepareUpdate(indexOrAlias(), "type1", "2")
|
||||
.setScript(new Script("field", ScriptService.ScriptType.INLINE, "field_inc", null)).execute().actionGet();
|
||||
getResponse = client().prepareGet("test", "type1", "2").setFields("_ttl").execute().actionGet();
|
||||
ttl = ((Number) getResponse.getField("_ttl").getValue()).longValue();
|
||||
assertThat(ttl, greaterThan(0L));
|
||||
|
||||
// check TTL update
|
||||
client().prepareUpdate(indexOrAlias(), "type1", "2")
|
||||
.setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("_ctx", Collections.singletonMap("_ttl", 3600000)))).execute().actionGet();
|
||||
getResponse = client().prepareGet("test", "type1", "2").setFields("_ttl").execute().actionGet();
|
||||
ttl = ((Number) getResponse.getField("_ttl").getValue()).longValue();
|
||||
assertThat(ttl, greaterThan(0L));
|
||||
assertThat(ttl, lessThanOrEqualTo(3600000L));
|
||||
|
||||
// check timestamp update
|
||||
client().prepareIndex("test", "type1", "3").setSource("field", 1).setRefreshPolicy(IMMEDIATE).get();
|
||||
client().prepareUpdate(indexOrAlias(), "type1", "3")
|
||||
.setScript(new Script("", ScriptService.ScriptType.INLINE, "put_values", Collections.singletonMap("_ctx", Collections.singletonMap("_timestamp", "2009-11-15T14:12:12")))).execute()
|
||||
.actionGet();
|
||||
getResponse = client().prepareGet("test", "type1", "3").setFields("_timestamp").execute().actionGet();
|
||||
long timestamp = ((Number) getResponse.getField("_timestamp").getValue()).longValue();
|
||||
assertThat(timestamp, equalTo(1258294332000L));
|
||||
|
||||
// check fields parameter
|
||||
client().prepareIndex("test", "type1", "1").setSource("field", 1).execute().actionGet();
|
||||
updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1")
|
||||
|
@ -682,7 +645,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
client().prepareIndex("test", "type1", "1").setSource("field", 1).execute().actionGet();
|
||||
updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1").setDoc(XContentFactory.jsonBuilder().startObject().field("field2", 2).endObject()).execute().actionGet();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
getResponse = client().prepareGet("test", "type1", "1").execute().actionGet();
|
||||
GetResponse getResponse = client().prepareGet("test", "type1", "1").execute().actionGet();
|
||||
assertThat(getResponse.getSourceAsMap().get("field").toString(), equalTo("1"));
|
||||
assertThat(getResponse.getSourceAsMap().get("field2").toString(), equalTo("2"));
|
||||
}
|
||||
|
@ -690,7 +653,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
// change existing field
|
||||
updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1").setDoc(XContentFactory.jsonBuilder().startObject().field("field", 3).endObject()).execute().actionGet();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
getResponse = client().prepareGet("test", "type1", "1").execute().actionGet();
|
||||
GetResponse getResponse = client().prepareGet("test", "type1", "1").execute().actionGet();
|
||||
assertThat(getResponse.getSourceAsMap().get("field").toString(), equalTo("3"));
|
||||
assertThat(getResponse.getSourceAsMap().get("field2").toString(), equalTo("2"));
|
||||
}
|
||||
|
@ -708,7 +671,7 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
client().prepareIndex("test", "type1", "1").setSource("map", testMap).execute().actionGet();
|
||||
updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1").setDoc(XContentFactory.jsonBuilder().startObject().field("map", testMap3).endObject()).execute().actionGet();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
getResponse = client().prepareGet("test", "type1", "1").execute().actionGet();
|
||||
GetResponse getResponse = client().prepareGet("test", "type1", "1").execute().actionGet();
|
||||
Map map1 = (Map) getResponse.getSourceAsMap().get("map");
|
||||
assertThat(map1.size(), equalTo(3));
|
||||
assertThat(map1.containsKey("map1"), equalTo(true));
|
||||
|
@ -760,16 +723,12 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
.addMapping("type1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("type1")
|
||||
.startObject("_timestamp").field("enabled", true).endObject()
|
||||
.startObject("_ttl").field("enabled", true).endObject()
|
||||
.endObject()
|
||||
.endObject())
|
||||
.addMapping("subtype1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("subtype1")
|
||||
.startObject("_parent").field("type", "type1").endObject()
|
||||
.startObject("_timestamp").field("enabled", true).endObject()
|
||||
.startObject("_ttl").field("enabled", true).endObject()
|
||||
.endObject()
|
||||
.endObject())
|
||||
);
|
||||
|
@ -813,7 +772,6 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
assertEquals(1, updateContext.get("_version"));
|
||||
assertEquals("parentId1", updateContext.get("_parent"));
|
||||
assertEquals("routing1", updateContext.get("_routing"));
|
||||
assertThat(((Integer) updateContext.get("_ttl")).longValue(), allOf(greaterThanOrEqualTo(ttl-3000), lessThanOrEqualTo(ttl)));
|
||||
|
||||
// Idem with the second object
|
||||
updateResponse = client().prepareUpdate("test", "type1", "parentId1")
|
||||
|
@ -904,13 +862,6 @@ public class UpdateIT extends ESIntegTestCase {
|
|||
public void testStressUpdateDeleteConcurrency() throws Exception {
|
||||
//We create an index with merging disabled so that deletes don't get merged away
|
||||
assertAcked(prepareCreate("test")
|
||||
.addMapping("type1", XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
.startObject("type1")
|
||||
.startObject("_timestamp").field("enabled", true).endObject()
|
||||
.startObject("_ttl").field("enabled", true).endObject()
|
||||
.endObject()
|
||||
.endObject())
|
||||
.setSettings(Settings.builder().put(MergePolicyConfig.INDEX_MERGE_ENABLED, false)));
|
||||
ensureGreen();
|
||||
|
||||
|
|
|
@ -127,26 +127,6 @@ Each bulk item can include the parent value using the `_parent`/`parent`
|
|||
field. It automatically follows the behavior of the index / delete
|
||||
operation based on the `_parent` / `_routing` mapping.
|
||||
|
||||
[float]
|
||||
[[bulk-timestamp]]
|
||||
=== Timestamp
|
||||
|
||||
deprecated[2.0.0,The `_timestamp` field is deprecated. Instead, use a normal <<date,`date`>> field and set its value explicitly]
|
||||
|
||||
Each bulk item can include the timestamp value using the
|
||||
`_timestamp`/`timestamp` field. It automatically follows the behavior of
|
||||
the index operation based on the `_timestamp` mapping.
|
||||
|
||||
[float]
|
||||
[[bulk-ttl]]
|
||||
=== TTL
|
||||
|
||||
deprecated[2.0.0,The current `_ttl` implementation is deprecated and will be replaced with a different implementation in a future version]
|
||||
|
||||
Each bulk item can include the ttl value using the `_ttl`/`ttl` field.
|
||||
It automatically follows the behavior of the index operation based on
|
||||
the `_ttl` mapping.
|
||||
|
||||
[float]
|
||||
[[bulk-consistency]]
|
||||
=== Write Consistency
|
||||
|
|
|
@ -290,70 +290,6 @@ When indexing a child document, the routing value is automatically set
|
|||
to be the same as its parent, unless the routing value is explicitly
|
||||
specified using the `routing` parameter.
|
||||
|
||||
[float]
|
||||
[[index-timestamp]]
|
||||
=== Timestamp
|
||||
|
||||
deprecated[2.0.0,The `_timestamp` field is deprecated. Instead, use a normal <<date,`date`>> field and set its value explicitly]
|
||||
|
||||
A document can be indexed with a `timestamp` associated with it. The
|
||||
`timestamp` value of a document can be set using the `timestamp`
|
||||
parameter. For example:
|
||||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
PUT twitter/tweet/1?timestamp=2009-11-15T14:12:12
|
||||
{
|
||||
"user" : "kimchy",
|
||||
"message" : "trying out Elasticsearch"
|
||||
}
|
||||
--------------------------------------------------
|
||||
// CONSOLE
|
||||
|
||||
If the `timestamp` value is not provided externally or in the `_source`,
|
||||
the `timestamp` will be automatically set to the date the document was
|
||||
processed by the indexing chain. More information can be found on the
|
||||
<<mapping-timestamp-field,_timestamp mapping
|
||||
page>>.
|
||||
|
||||
[float]
|
||||
[[index-ttl]]
|
||||
=== TTL
|
||||
|
||||
deprecated[2.0.0,The current `_ttl` implementation is deprecated and will be replaced with a different implementation in a future version]
|
||||
|
||||
|
||||
A document can be indexed with a `ttl` (time to live) associated with
|
||||
it. Expired documents will be expunged automatically. The expiration
|
||||
date that will be set for a document with a provided `ttl` is relative
|
||||
to the `timestamp` of the document, meaning it can be based on the time
|
||||
of indexing or on any time provided. The provided `ttl` must be strictly
|
||||
positive and can be a number (in milliseconds) or any valid time value
|
||||
as shown in the following examples:
|
||||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
PUT twitter/tweet/1?ttl=86400000ms
|
||||
{
|
||||
"user": "kimchy",
|
||||
"message": "Trying out elasticsearch, so far so good?"
|
||||
}
|
||||
--------------------------------------------------
|
||||
// CONSOLE
|
||||
|
||||
[source,js]
|
||||
--------------------------------------------------
|
||||
PUT twitter/tweet/1?ttl=1d
|
||||
{
|
||||
"user": "kimchy",
|
||||
"message": "Trying out elasticsearch, so far so good?"
|
||||
}
|
||||
--------------------------------------------------
|
||||
// CONSOLE
|
||||
|
||||
More information can be found on the
|
||||
<<mapping-ttl-field,_ttl mapping page>>.
|
||||
|
||||
[float]
|
||||
[[index-distributed]]
|
||||
=== Distributed
|
||||
|
|
|
@ -272,8 +272,6 @@ change:
|
|||
* `_version`
|
||||
* `_routing`
|
||||
* `_parent`
|
||||
* `_timestamp`
|
||||
* `_ttl`
|
||||
|
||||
Setting `_version` to `null` or clearing it from the `ctx` map is just like not
|
||||
sending the version in an indexing request. It will cause that document to be
|
||||
|
|
|
@ -57,7 +57,7 @@ curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
|
|||
|
||||
In addition to `_source`, the following variables are available through
|
||||
the `ctx` map: `_index`, `_type`, `_id`, `_version`, `_routing`,
|
||||
`_parent`, `_timestamp`, `_ttl`.
|
||||
`_parent`.
|
||||
|
||||
We can also add a new field to the document:
|
||||
|
||||
|
|
|
@ -131,11 +131,6 @@ specific index module:
|
|||
|
||||
Set to `true` to disable index metadata reads and writes.
|
||||
|
||||
`index.ttl.disable_purge`::
|
||||
|
||||
experimental[] Disables the purge of <<mapping-ttl-field,expired docs>> on
|
||||
the current index.
|
||||
|
||||
`index.max_refresh_listeners`::
|
||||
|
||||
Maximum number of refresh listeners available on each shard of the index.
|
||||
|
|
|
@ -439,8 +439,7 @@ The following example sets the `_id` metadata field of a document to `1`:
|
|||
}
|
||||
--------------------------------------------------
|
||||
|
||||
The following metadata fields are accessible by a processor: `_index`, `_type`, `_id`, `_routing`, `_parent`,
|
||||
`_timestamp`, and `_ttl`.
|
||||
The following metadata fields are accessible by a processor: `_index`, `_type`, `_id`, `_routing`, `_parent`.
|
||||
|
||||
[float]
|
||||
[[accessing-ingest-metadata]]
|
||||
|
|
|
@ -48,14 +48,6 @@ can be customised when a mapping type is created.
|
|||
|
||||
All fields in the document which contain non-null values.
|
||||
|
||||
<<mapping-timestamp-field,`_timestamp`>>::
|
||||
|
||||
A timestamp associated with the document, either specified manually or auto-generated.
|
||||
|
||||
<<mapping-ttl-field,`_ttl`>>::
|
||||
|
||||
How long a document should live before it is automatically deleted.
|
||||
|
||||
[float]
|
||||
=== Routing meta-fields
|
||||
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
[[mapping-timestamp-field]]
|
||||
=== `_timestamp` field
|
||||
|
||||
deprecated[2.0.0,The `_timestamp` field is deprecated. Instead, use a normal <<date,`date`>> field and set its value explicitly]
|
||||
|
||||
The `_timestamp` field, when enabled, allows a timestamp to be indexed and
|
||||
stored with a document. The timestamp may be specified manually, generated
|
||||
automatically, or set to a default value:
|
||||
|
||||
[source,js]
|
||||
------------------------------------
|
||||
PUT my_index
|
||||
{
|
||||
"mappings": {
|
||||
"my_type": {
|
||||
"_timestamp": { <1>
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PUT my_index/my_type/1?timestamp=2015-01-01 <2>
|
||||
{ "text": "Timestamp as a formatted date" }
|
||||
|
||||
PUT my_index/my_type/2?timestamp=1420070400000 <3>
|
||||
{ "text": "Timestamp as milliseconds since the epoch" }
|
||||
|
||||
PUT my_index/my_type/3 <4>
|
||||
{ "text": "Autogenerated timestamp set to now()" }
|
||||
|
||||
------------------------------------
|
||||
// CONSOLE
|
||||
|
||||
<1> Enable the `_timestamp` field with default settings.
|
||||
<2> Set the timestamp manually with a formatted date.
|
||||
<3> Set the timestamp with milliseconds since the epoch.
|
||||
<4> Auto-generates a timestamp with <<date-math,now()>>.
|
||||
|
||||
The behaviour of the `_timestamp` field can be configured with the following parameters:
|
||||
|
||||
`default`::
|
||||
|
||||
A default value to be used if none is provided. Defaults to <<date-math,now()>>.
|
||||
|
||||
`format`::
|
||||
|
||||
The <<mapping-date-format,date format>> (or formats) to use when parsing timestamps. Defaults to `epoch_millis||strictDateOptionalTime`.
|
||||
|
||||
`ignore_missing`::
|
||||
|
||||
If `true` (default), replace missing timestamps with the `default` value. If `false`, throw an exception.
|
||||
|
||||
|
||||
The value of the `_timestamp` field is accessible in queries, aggregations, scripts,
|
||||
and when sorting:
|
||||
|
||||
[source,js]
|
||||
--------------------------
|
||||
GET my_index/_search
|
||||
{
|
||||
"query": {
|
||||
"range": {
|
||||
"_timestamp": { <1>
|
||||
"gte": "2015-01-01"
|
||||
}
|
||||
}
|
||||
},
|
||||
"aggs": {
|
||||
"Timestamps": {
|
||||
"terms": {
|
||||
"field": "_timestamp", <2>
|
||||
"size": 10
|
||||
}
|
||||
}
|
||||
},
|
||||
"sort": [
|
||||
{
|
||||
"_timestamp": { <3>
|
||||
"order": "desc"
|
||||
}
|
||||
}
|
||||
],
|
||||
"script_fields": {
|
||||
"Timestamp": {
|
||||
"script": "doc['_timestamp']" <4>
|
||||
}
|
||||
}
|
||||
}
|
||||
--------------------------
|
||||
// CONSOLE
|
||||
// TEST[continued]
|
||||
|
||||
<1> Querying on the `_timestamp` field
|
||||
<2> Aggregating on the `_timestamp` field
|
||||
<3> Sorting on the `_timestamp` field
|
||||
<4> Accessing the `_timestamp` field in scripts (inline scripts must be <<enable-dynamic-scripting,enabled>> for this example to work)
|
|
@ -1,112 +0,0 @@
|
|||
[[mapping-ttl-field]]
|
||||
=== `_ttl` field
|
||||
|
||||
deprecated[2.0.0,The current `_ttl` implementation is deprecated and will be replaced with a different implementation in a future version]
|
||||
|
||||
Some types of documents, such as session data or special offers, come with an
|
||||
expiration date. The `_ttl` field allows you to specify the minimum time a
|
||||
document should live, after which time the document is deleted automatically.
|
||||
|
||||
[TIP]
|
||||
.Prefer index-per-timeframe to TTL
|
||||
======================================================
|
||||
|
||||
With TTL , expired documents first have to be marked as deleted then later
|
||||
purged from the index when segments are merged. For append-only time-based
|
||||
data such as log events, it is much more efficient to use an index-per-day /
|
||||
week / month instead of TTLs. Old log data can be removed by simply deleting
|
||||
old indices.
|
||||
|
||||
======================================================
|
||||
|
||||
The `_ttl` field may be enabled as follows:
|
||||
|
||||
[source,js]
|
||||
-------------------------------
|
||||
PUT my_index
|
||||
{
|
||||
"mappings": {
|
||||
"my_type": {
|
||||
"_ttl": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PUT my_index/my_type/1?ttl=10m <1>
|
||||
{
|
||||
"text": "Will expire in 10 minutes"
|
||||
}
|
||||
|
||||
PUT my_index/my_type/2 <2>
|
||||
{
|
||||
"text": "Will not expire"
|
||||
}
|
||||
-------------------------------
|
||||
// CONSOLE
|
||||
<1> This document will expire 10 minutes after being indexed.
|
||||
<2> This document has no TTL set and will not expire.
|
||||
|
||||
The expiry time is calculated as the value of the
|
||||
<<mapping-timestamp-field,`_timestamp`>> field (or `now()` if the `_timestamp`
|
||||
is not enabled) plus the `ttl` specified in the indexing request.
|
||||
|
||||
==== Default TTL
|
||||
|
||||
You can provide a default `_ttl`, which will be applied to indexing requests where the `ttl` is not specified:
|
||||
|
||||
[source,js]
|
||||
-------------------------------
|
||||
PUT my_index
|
||||
{
|
||||
"mappings": {
|
||||
"my_type": {
|
||||
"_ttl": {
|
||||
"enabled": true,
|
||||
"default": "5m"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PUT my_index/my_type/1?ttl=10m <1>
|
||||
{
|
||||
"text": "Will expire in 10 minutes"
|
||||
}
|
||||
|
||||
PUT my_index/my_type/2 <2>
|
||||
{
|
||||
"text": "Will expire in 5 minutes"
|
||||
}
|
||||
-------------------------------
|
||||
// CONSOLE
|
||||
<1> This document will expire 10 minutes after being indexed.
|
||||
<2> This document has no TTL set and so will expire after the default 5 minutes.
|
||||
|
||||
The `default` value can use <<time-units,time units>> like `d` for days, and
|
||||
will use `ms` as the default unit if no time unit is provided.
|
||||
|
||||
You can dynamically update the `default` value using the put mapping
|
||||
API. It won't change the `_ttl` of already indexed documents but will be
|
||||
used for future documents.
|
||||
|
||||
==== Note on documents expiration
|
||||
|
||||
Expired documents will be automatically deleted periodically. The following
|
||||
settings control the expiry process:
|
||||
|
||||
`indices.ttl.interval`::
|
||||
|
||||
How often the purge process should run. Defaults to `60s`. Expired documents
|
||||
may still be retrieved before they are purged.
|
||||
|
||||
`indices.ttl.bulk_size`::
|
||||
|
||||
How many deletions are handled by a single <<docs-bulk,`bulk`>> request. The
|
||||
default value is `10000`.
|
||||
|
||||
==== Note on `detect_noop`
|
||||
If an update tries to update just the `_ttl` without changing the `_source` of
|
||||
the document it's expiration time won't be updated if `detect_noop` is `true`.
|
||||
In 2.1 `detect_noop` defaults to `true`.
|
|
@ -76,6 +76,14 @@ PUT my_index
|
|||
Also the `precision_step` parameter is now irrelevant and will be rejected on
|
||||
indices that are created on or after 5.0.
|
||||
|
||||
==== `_timestamp` and `_ttl`
|
||||
|
||||
The `_timestamp` and `_ttl` fields were deprecated and are now removed. As a
|
||||
replacement for `_timestamp`, you should populate a regular date field with the
|
||||
current timestamp on application side. For `_ttl`, you should either use
|
||||
time-based indices when applicable, or cron a delete-by-query with a range
|
||||
query on a timestamp field
|
||||
|
||||
==== `index` property
|
||||
|
||||
On all field datatypes (except for the deprecated `string` field), the `index`
|
||||
|
|
|
@ -30,10 +30,6 @@ Available settings include:
|
|||
|
||||
Control the resource limits on the shard recovery process.
|
||||
|
||||
<<indices-ttl,TTL interval>>::
|
||||
|
||||
Control how expired documents are removed.
|
||||
|
||||
include::indices/circuit_breaker.asciidoc[]
|
||||
|
||||
include::indices/fielddata.asciidoc[]
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
[[indices-ttl]]
|
||||
=== TTL interval
|
||||
|
||||
Documents that have a <<mapping-ttl-field,`ttl`>> value set need to be deleted
|
||||
once they have expired. How and how often they are deleted is controlled by
|
||||
the following dynamic cluster settings:
|
||||
|
||||
`indices.ttl.interval`::
|
||||
|
||||
How often the deletion process runs. Defaults to `60s`.
|
||||
|
||||
`indices.ttl.bulk_size`::
|
||||
|
||||
The deletions are processed with a <<docs-bulk,bulk request>>.
|
||||
The number of deletions processed can be configured with
|
||||
this settings. Defaults to `10000`.
|
|
@ -22,7 +22,6 @@ package org.elasticsearch.messy.tests;
|
|||
import org.elasticsearch.action.index.IndexRequestBuilder;
|
||||
import org.elasticsearch.action.search.SearchRequestBuilder;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.action.support.WriteRequest;
|
||||
import org.elasticsearch.common.Priority;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
|
@ -45,7 +44,6 @@ import org.elasticsearch.test.ESIntegTestCase;
|
|||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
|
@ -88,8 +86,6 @@ public class SearchFieldsTests extends ESIntegTestCase {
|
|||
client().admin().cluster().prepareHealth().setWaitForEvents(Priority.LANGUID).setWaitForYellowStatus().execute().actionGet();
|
||||
|
||||
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type1")
|
||||
// _timestamp is randomly enabled via templates but we don't want it here to test stored fields behaviour
|
||||
.startObject("_timestamp").field("enabled", false).endObject()
|
||||
.startObject("properties")
|
||||
.startObject("field1").field("type", "text").field("store", true).endObject()
|
||||
.startObject("field2").field("type", "text").field("store", false).endObject()
|
||||
|
@ -698,7 +694,7 @@ public class SearchFieldsTests extends ESIntegTestCase {
|
|||
public void testLoadMetadata() throws Exception {
|
||||
assertAcked(prepareCreate("test")
|
||||
.addMapping("parent")
|
||||
.addMapping("my-type1", "_timestamp", "enabled=true", "_ttl", "enabled=true", "_parent", "type=parent"));
|
||||
.addMapping("my-type1", "_parent", "type=parent"));
|
||||
|
||||
indexRandom(true,
|
||||
client().prepareIndex("test", "my-type1", "1")
|
||||
|
@ -717,12 +713,6 @@ public class SearchFieldsTests extends ESIntegTestCase {
|
|||
assertThat(fields.get("field1"), nullValue());
|
||||
assertThat(fields.get("_routing").isMetadataField(), equalTo(true));
|
||||
assertThat(fields.get("_routing").getValue().toString(), equalTo("1"));
|
||||
assertThat(fields.get("_timestamp").isMetadataField(), equalTo(true));
|
||||
assertThat(fields.get("_timestamp").getValue().toString(), equalTo("205097"));
|
||||
assertThat(fields.get("_ttl").isMetadataField(), equalTo(true));
|
||||
// TODO: _ttl should return the original value, but it does not work today because
|
||||
// it would use now() instead of the value of _timestamp to rebase
|
||||
// assertThat(fields.get("_ttl").getValue().toString(), equalTo("10000000205097"));
|
||||
assertThat(fields.get("_parent").isMetadataField(), equalTo(true));
|
||||
assertThat(fields.get("_parent").getValue().toString(), equalTo("parent_1"));
|
||||
}
|
||||
|
|
|
@ -255,7 +255,7 @@ Supports also regular expressions with flag X for more readability (accepts whit
|
|||
Compares two numeric values, eg:
|
||||
|
||||
....
|
||||
- lt: { _ttl: 10000 } # the `_ttl` value is less than 10,000
|
||||
- lt: { foo: 10000 } # the `foo` value is less than 10,000
|
||||
....
|
||||
|
||||
=== `lte` and `gte`
|
||||
|
@ -263,7 +263,7 @@ Compares two numeric values, eg:
|
|||
Compares two numeric values, eg:
|
||||
|
||||
....
|
||||
- lte: { _ttl: 10000 } # the `_ttl` value is less than or equal to 10,000
|
||||
- lte: { foo: 10000 } # the `foo` value is less than or equal to 10,000
|
||||
....
|
||||
|
||||
=== `length`
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
---
|
||||
"Timestamp":
|
||||
|
||||
- do:
|
||||
indices.create:
|
||||
index: test_1
|
||||
body:
|
||||
mappings:
|
||||
test:
|
||||
_timestamp:
|
||||
enabled: 1
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
# blank timestamp
|
||||
- do:
|
||||
create:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _timestamp
|
||||
|
||||
- is_true: _timestamp
|
||||
|
||||
# milliseconds since epoch
|
||||
|
||||
- do:
|
||||
delete:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
- do:
|
||||
create:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
timestamp: 1372011280000
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _timestamp
|
||||
|
||||
- match: { _timestamp: 1372011280000 }
|
||||
|
||||
# date format
|
||||
|
||||
- do:
|
||||
delete:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
- do:
|
||||
create:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
timestamp: 2013-06-23T18:14:40
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _timestamp
|
||||
|
||||
- match: { _timestamp: 1372011280000 }
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
---
|
||||
"TTL":
|
||||
|
||||
- do:
|
||||
indices.create:
|
||||
index: test_1
|
||||
body:
|
||||
mappings:
|
||||
test:
|
||||
_ttl:
|
||||
enabled: 1
|
||||
default: 10s
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
# blank ttl
|
||||
- do:
|
||||
create:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _ttl
|
||||
|
||||
- lte: { _ttl: 10000}
|
||||
- gt: { _ttl: 0}
|
||||
|
||||
# milliseconds
|
||||
|
||||
- do:
|
||||
delete:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
- do:
|
||||
create:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
ttl: 100000ms
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _ttl
|
||||
|
||||
- lte: { _ttl: 100000}
|
||||
- gt: { _ttl: 10000}
|
||||
|
||||
# duration
|
||||
|
||||
- do:
|
||||
delete:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
- do:
|
||||
create:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
ttl: 20s
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _ttl
|
||||
|
||||
- lte: { _ttl: 20000}
|
||||
- gt: { _ttl: 10000}
|
||||
|
||||
# with timestamp
|
||||
|
||||
- do:
|
||||
delete:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
- do:
|
||||
catch: /already_expired_exception/
|
||||
create:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
ttl: 20s
|
||||
timestamp: 2013-06-23T18:14:40
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
---
|
||||
"Timestamp":
|
||||
|
||||
- do:
|
||||
indices.create:
|
||||
index: test_1
|
||||
body:
|
||||
mappings:
|
||||
test:
|
||||
_timestamp:
|
||||
enabled: 1
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
# blank timestamp
|
||||
- do:
|
||||
index:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _timestamp
|
||||
|
||||
- is_true: _timestamp
|
||||
|
||||
# milliseconds since epoch
|
||||
|
||||
- do:
|
||||
index:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
timestamp: 1372011280000
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _timestamp
|
||||
|
||||
- match: { _timestamp: 1372011280000 }
|
||||
|
||||
# date format
|
||||
|
||||
- do:
|
||||
index:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
timestamp: 2013-06-23T18:14:40
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _timestamp
|
||||
|
||||
- match: { _timestamp: 1372011280000 }
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
---
|
||||
"TTL":
|
||||
|
||||
- do:
|
||||
indices.create:
|
||||
index: test_1
|
||||
body:
|
||||
mappings:
|
||||
test:
|
||||
_ttl:
|
||||
enabled: 1
|
||||
default: 10s
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
# blank ttl
|
||||
- do:
|
||||
index:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _ttl
|
||||
|
||||
- lte: { _ttl: 10000}
|
||||
- gt: { _ttl: 0}
|
||||
|
||||
# milliseconds
|
||||
|
||||
- do:
|
||||
index:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
ttl: 100000ms
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _ttl
|
||||
|
||||
- lte: { _ttl: 100000}
|
||||
- gt: { _ttl: 10000}
|
||||
|
||||
# duration
|
||||
|
||||
- do:
|
||||
index:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
ttl: 20s
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _ttl
|
||||
|
||||
- lte: { _ttl: 20000}
|
||||
- gt: { _ttl: 10000}
|
||||
|
||||
# with timestamp
|
||||
|
||||
- do:
|
||||
catch: /already_expired_exception/
|
||||
index:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
ttl: 20s
|
||||
timestamp: 2013-06-23T18:14:40
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
---
|
||||
"Timestamp":
|
||||
|
||||
- do:
|
||||
indices.create:
|
||||
index: test_1
|
||||
body:
|
||||
mappings:
|
||||
test:
|
||||
_timestamp:
|
||||
enabled: 1
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
# blank timestamp
|
||||
- do:
|
||||
update:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body:
|
||||
doc: { foo: baz }
|
||||
upsert: { foo: bar }
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _timestamp
|
||||
|
||||
- is_true: _timestamp
|
||||
|
||||
# milliseconds since epoch
|
||||
|
||||
- do:
|
||||
update:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body:
|
||||
doc: { foo: baz }
|
||||
upsert: { foo: bar }
|
||||
timestamp: 1372011280000
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _timestamp
|
||||
|
||||
- match: { _timestamp: 1372011280000 }
|
||||
|
||||
# date format
|
||||
|
||||
- do:
|
||||
update:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body:
|
||||
doc: { foo: baz }
|
||||
upsert: { foo: bar }
|
||||
timestamp: 2013-06-23T18:14:40
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _timestamp
|
||||
|
||||
- match: { _timestamp: 1372011280000 }
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
---
|
||||
"TTL":
|
||||
|
||||
- do:
|
||||
indices.create:
|
||||
index: test_1
|
||||
body:
|
||||
mappings:
|
||||
test:
|
||||
_ttl:
|
||||
enabled: 1
|
||||
default: 10s
|
||||
- do:
|
||||
cluster.health:
|
||||
wait_for_status: yellow
|
||||
|
||||
# blank ttl
|
||||
- do:
|
||||
update:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body:
|
||||
doc: { foo: baz }
|
||||
upsert: { foo: bar }
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _ttl
|
||||
|
||||
- lte: { _ttl: 10000}
|
||||
- gt: { _ttl: 0}
|
||||
|
||||
# milliseconds
|
||||
|
||||
- do:
|
||||
update:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body:
|
||||
doc: { foo: baz }
|
||||
upsert: { foo: bar }
|
||||
ttl: 100000ms
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _ttl
|
||||
|
||||
- lte: { _ttl: 100000}
|
||||
- gt: { _ttl: 10000}
|
||||
|
||||
# seconds
|
||||
|
||||
- do:
|
||||
update:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body:
|
||||
doc: { foo: baz }
|
||||
upsert: { foo: bar }
|
||||
detect_noop: false
|
||||
ttl: 20s
|
||||
|
||||
- do:
|
||||
get:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
fields: _ttl
|
||||
|
||||
- lte: { _ttl: 20000}
|
||||
- gt: { _ttl: 10000}
|
||||
|
||||
# with timestamp
|
||||
|
||||
- do:
|
||||
catch: /already_expired_exception/
|
||||
index:
|
||||
index: test_1
|
||||
type: test
|
||||
id: 1
|
||||
body: { foo: bar }
|
||||
ttl: 20s
|
||||
timestamp: 2013-06-23T18:14:40
|
|
@ -12,11 +12,6 @@
|
|||
mappings:
|
||||
test:
|
||||
_parent: { type: "foo" }
|
||||
_timestamp:
|
||||
enabled: 1
|
||||
_ttl:
|
||||
enabled: 1
|
||||
default: 10s
|
||||
|
||||
- do:
|
||||
cluster.health:
|
||||
|
@ -28,15 +23,13 @@
|
|||
type: test
|
||||
id: 1
|
||||
parent: 5
|
||||
fields: [ _parent, _routing, _timestamp, _ttl ]
|
||||
fields: [ _parent, _routing ]
|
||||
body:
|
||||
doc: { foo: baz }
|
||||
upsert: { foo: bar }
|
||||
|
||||
- match: { get._parent: "5" }
|
||||
- match: { get._routing: "5" }
|
||||
- is_true: get._timestamp
|
||||
- is_true: get._ttl
|
||||
|
||||
- do:
|
||||
get:
|
||||
|
@ -44,6 +37,6 @@
|
|||
type: test
|
||||
id: 1
|
||||
parent: 5
|
||||
fields: [ _parent, _routing, _timestamp, _ttl ]
|
||||
fields: [ _parent, _routing ]
|
||||
|
||||
|
||||
|
|
|
@ -383,13 +383,7 @@ public abstract class ESIntegTestCase extends ESTestCase {
|
|||
|
||||
XContentBuilder mappings = null;
|
||||
if (frequently() && randomDynamicTemplates()) {
|
||||
mappings = XContentFactory.jsonBuilder().startObject().startObject("_default_");
|
||||
if (randomBoolean()) {
|
||||
mappings.startObject(TimestampFieldMapper.NAME)
|
||||
.field("enabled", randomBoolean());
|
||||
mappings.endObject();
|
||||
}
|
||||
mappings.endObject().endObject();
|
||||
mappings = XContentFactory.jsonBuilder().startObject().startObject("_default_").endObject().endObject();
|
||||
}
|
||||
|
||||
for (String setting : randomSettingsBuilder.internalMap().keySet()) {
|
||||
|
|
Loading…
Reference in New Issue