add the ability to define meta _attributes for mapping, basically a place to store additional unstructured data on the mapping
This commit is contained in:
parent
3770924300
commit
cb9be9973b
|
@ -226,7 +226,7 @@ public class MetaDataService extends AbstractComponent {
|
|||
.initializeEmpty(newMetaData.index(index));
|
||||
routingTableBuilder.add(indexRoutingBuilder);
|
||||
|
||||
logger.info("creating index [{}], cause [{}], shards [{}]/[{}], mappings {}", index, cause, indexMetaData.numberOfShards(), indexMetaData.numberOfReplicas(), fMappings.keySet());
|
||||
logger.info("[{}] creating index, cause [{}], shards [{}]/[{}], mappings {}", index, cause, indexMetaData.numberOfShards(), indexMetaData.numberOfReplicas(), fMappings.keySet());
|
||||
RoutingTable newRoutingTable = shardsRoutingStrategy.reroute(newClusterStateBuilder().state(currentState).routingTable(routingTableBuilder).metaData(newMetaData).build());
|
||||
return newClusterStateBuilder().state(currentState).routingTable(newRoutingTable).metaData(newMetaData).build();
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ public class MetaDataService extends AbstractComponent {
|
|||
throw new IndexMissingException(new Index(index));
|
||||
}
|
||||
|
||||
logger.info("deleting index [{}]", index);
|
||||
logger.info("[{}] deleting index", index);
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(clusterService.state().nodes().size());
|
||||
NodeIndexDeletedAction.Listener listener = new NodeIndexDeletedAction.Listener() {
|
||||
|
@ -320,9 +320,9 @@ public class MetaDataService extends AbstractComponent {
|
|||
// build the updated mapping source
|
||||
final String updatedMappingSource = existingMapper.buildSource();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("index [" + index + "]: Update mapping [" + type + "] (dynamic) with source [" + updatedMappingSource + "]");
|
||||
logger.debug("[{}] update mapping [{}] (dynamic) with source [{}]", index, type, updatedMappingSource);
|
||||
} else if (logger.isInfoEnabled()) {
|
||||
logger.info("index [" + index + "]: Update mapping [" + type + "] (dynamic)");
|
||||
logger.info("[{}] update mapping [{}] (dynamic)", index, type);
|
||||
}
|
||||
// publish the new mapping
|
||||
clusterService.submitStateUpdateTask("update-mapping [" + index + "][" + type + "]", new ClusterStateUpdateTask() {
|
||||
|
@ -396,9 +396,9 @@ public class MetaDataService extends AbstractComponent {
|
|||
}
|
||||
mappings.put(index, mapping);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("index [" + index + "]: Put mapping [" + mapping.v1() + "] with source [" + mapping.v2() + "]");
|
||||
logger.debug("[{}] put_mapping [{}] with source [{}]", index, mapping.v1(), mapping.v2());
|
||||
} else if (logger.isInfoEnabled()) {
|
||||
logger.info("index [" + index + "]: Put mapping [" + mapping.v1() + "]");
|
||||
logger.info("[{}] put_mapping [{}]", index, mapping.v1());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.index.mapper;
|
|||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.elasticsearch.common.collect.ImmutableMap;
|
||||
import org.elasticsearch.common.util.concurrent.ThreadSafe;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
@ -39,6 +40,11 @@ public interface DocumentMapper {
|
|||
*/
|
||||
String mappingSource();
|
||||
|
||||
/**
|
||||
* Attributes of this type mappings.
|
||||
*/
|
||||
ImmutableMap<String, Object> attributes();
|
||||
|
||||
/**
|
||||
* Generates the source of the mapper based on the current mappings.
|
||||
*/
|
||||
|
|
|
@ -46,7 +46,7 @@ import java.net.URL;
|
|||
import static org.elasticsearch.common.collect.MapBuilder.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
@ThreadSafe
|
||||
public class MapperService extends AbstractIndexComponent implements Iterable<DocumentMapper> {
|
||||
|
@ -60,8 +60,6 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
|||
|
||||
private final URL dynamicMappingUrl;
|
||||
|
||||
private final ClassLoader indexClassLoader;
|
||||
|
||||
private final String dynamicMappingSource;
|
||||
|
||||
private volatile ImmutableMap<String, DocumentMapper> mappers = ImmutableMap.of();
|
||||
|
@ -87,7 +85,6 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
|||
super(index, indexSettings);
|
||||
this.documentParser = new XContentDocumentMapperParser(analysisService);
|
||||
this.searchAnalyzer = new SmartIndexNameSearchAnalyzer(analysisService.defaultSearchAnalyzer());
|
||||
this.indexClassLoader = indexSettings.getClassLoader();
|
||||
|
||||
this.dynamic = componentSettings.getAsBoolean("dynamic", true);
|
||||
String dynamicMappingLocation = componentSettings.get("dynamic_mapping_location");
|
||||
|
@ -97,7 +94,7 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
|||
dynamicMappingUrl = environment.resolveConfig("dynamic-mapping.json");
|
||||
} catch (FailedToResolveConfigException e) {
|
||||
// not there, default to the built in one
|
||||
dynamicMappingUrl = indexClassLoader.getResource("org/elasticsearch/index/mapper/xcontent/dynamic-mapping.json");
|
||||
dynamicMappingUrl = indexSettings.getClassLoader().getResource("org/elasticsearch/index/mapper/xcontent/dynamic-mapping.json");
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
|
@ -127,7 +124,7 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
|||
} else {
|
||||
dynamicMappingSource = null;
|
||||
}
|
||||
logger.debug("Using dynamic[{}] with location[{}] and source[{}]", new Object[]{dynamic, dynamicMappingLocation, dynamicMappingSource});
|
||||
logger.debug("using dynamic[{}] with location[{}] and source[{}]", dynamic, dynamicMappingLocation, dynamicMappingSource);
|
||||
}
|
||||
|
||||
@Override public UnmodifiableIterator<DocumentMapper> iterator() {
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.index.mapper.xcontent;
|
|||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.elasticsearch.common.Preconditions;
|
||||
import org.elasticsearch.common.collect.ImmutableMap;
|
||||
import org.elasticsearch.common.thread.ThreadLocals;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
|
@ -64,12 +65,19 @@ public class XContentDocumentMapper implements DocumentMapper, ToXContent {
|
|||
|
||||
private String mappingSource;
|
||||
|
||||
private ImmutableMap<String, Object> attributes = ImmutableMap.of();
|
||||
|
||||
private XContentMapper.BuilderContext builderContext = new XContentMapper.BuilderContext(new ContentPath(1));
|
||||
|
||||
public Builder(XContentObjectMapper.Builder builder) {
|
||||
this.rootObjectMapper = builder.build(builderContext);
|
||||
}
|
||||
|
||||
public Builder attributes(ImmutableMap<String, Object> attributes) {
|
||||
this.attributes = attributes;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder sourceField(XContentSourceFieldMapper.Builder builder) {
|
||||
this.sourceFieldMapper = builder.build(builderContext);
|
||||
return this;
|
||||
|
@ -125,7 +133,7 @@ public class XContentDocumentMapper implements DocumentMapper, ToXContent {
|
|||
|
||||
public XContentDocumentMapper build() {
|
||||
Preconditions.checkNotNull(rootObjectMapper, "Mapper builder must have the root object mapper set");
|
||||
return new XContentDocumentMapper(rootObjectMapper, uidFieldMapper, idFieldMapper, typeFieldMapper,
|
||||
return new XContentDocumentMapper(rootObjectMapper, attributes, uidFieldMapper, idFieldMapper, typeFieldMapper,
|
||||
sourceFieldMapper, allFieldMapper, indexAnalyzer, searchAnalyzer, boostFieldMapper, mappingSource);
|
||||
}
|
||||
}
|
||||
|
@ -139,6 +147,8 @@ public class XContentDocumentMapper implements DocumentMapper, ToXContent {
|
|||
|
||||
private final String type;
|
||||
|
||||
private volatile ImmutableMap<String, Object> attributes;
|
||||
|
||||
private volatile String mappingSource;
|
||||
|
||||
private final XContentUidFieldMapper uidFieldMapper;
|
||||
|
@ -166,6 +176,7 @@ public class XContentDocumentMapper implements DocumentMapper, ToXContent {
|
|||
private final Object mutex = new Object();
|
||||
|
||||
public XContentDocumentMapper(XContentObjectMapper rootObjectMapper,
|
||||
ImmutableMap<String, Object> attributes,
|
||||
XContentUidFieldMapper uidFieldMapper,
|
||||
XContentIdFieldMapper idFieldMapper,
|
||||
XContentTypeFieldMapper typeFieldMapper,
|
||||
|
@ -175,6 +186,7 @@ public class XContentDocumentMapper implements DocumentMapper, ToXContent {
|
|||
@Nullable XContentBoostFieldMapper boostFieldMapper,
|
||||
@Nullable String mappingSource) {
|
||||
this.type = rootObjectMapper.name();
|
||||
this.attributes = attributes;
|
||||
this.mappingSource = mappingSource;
|
||||
this.rootObjectMapper = rootObjectMapper;
|
||||
this.uidFieldMapper = uidFieldMapper;
|
||||
|
@ -220,6 +232,10 @@ public class XContentDocumentMapper implements DocumentMapper, ToXContent {
|
|||
return this.type;
|
||||
}
|
||||
|
||||
@Override public ImmutableMap<String, Object> attributes() {
|
||||
return this.attributes;
|
||||
}
|
||||
|
||||
@Override public String mappingSource() {
|
||||
return this.mappingSource;
|
||||
}
|
||||
|
@ -367,7 +383,9 @@ public class XContentDocumentMapper implements DocumentMapper, ToXContent {
|
|||
MergeContext mergeContext = new MergeContext(this, mergeFlags);
|
||||
rootObjectMapper.merge(xContentMergeWith.rootObjectMapper, mergeContext);
|
||||
if (!mergeFlags.simulate()) {
|
||||
// update the source to the merged one
|
||||
// let the merge with attributes to override the attributes
|
||||
attributes = mergeWith.attributes();
|
||||
// update the source of the merged one
|
||||
mappingSource = buildSource();
|
||||
}
|
||||
return new MergeResult(mergeContext.buildConflicts());
|
||||
|
|
|
@ -149,6 +149,12 @@ public class XContentDocumentMapperParser implements DocumentMapperParser {
|
|||
docBuilder.searchAnalyzer(analysisService.defaultSearchAnalyzer());
|
||||
}
|
||||
|
||||
ImmutableMap<String, Object> attributes = ImmutableMap.of();
|
||||
if (rootObj.containsKey("_attributes")) {
|
||||
attributes = ImmutableMap.copyOf((Map<String, Object>) rootObj.get("_attributes"));
|
||||
}
|
||||
docBuilder.attributes(attributes);
|
||||
|
||||
docBuilder.mappingSource(source);
|
||||
|
||||
XContentDocumentMapper documentMapper = docBuilder.build();
|
||||
|
|
|
@ -78,6 +78,9 @@ public class SimpleXContentMapperTests {
|
|||
@Test public void testSimpleParser() throws Exception {
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/simple/test-mapping.json");
|
||||
XContentDocumentMapper docMapper = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
|
||||
assertThat((String) docMapper.attributes().get("param1"), equalTo("value1"));
|
||||
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/simple/test1.json");
|
||||
Document doc = docMapper.parse(json).doc();
|
||||
assertThat(doc.get(docMapper.uidMapper().names().indexName()), equalTo(Uid.createUid("person", "1")));
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
{
|
||||
person : {
|
||||
"_attributes" : {
|
||||
"param1" : "value1"
|
||||
},
|
||||
date_formats : ["yyyy-MM-dd", "dd-MM-yyyy"],
|
||||
dynamic : false,
|
||||
enabled : true,
|
||||
|
|
Loading…
Reference in New Issue