将映射添加到Java的一个types – 我该怎么做?

我试图用Java API或多或less地重新创build这个例子 。

我想我需要的只是添加一个映射到索引,但Java API文档不完全清楚如何做到这一点。

请告诉我如何在Java中创build一个与文档中的示例相同的映射:

curl -X PUT localhost:9200/test/tweet/_mapping -d '{ "tweet" : { "_ttl" : { "enabled" : true, "default" : "1d" } } }' 

这是我的代码:

 package foo; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import java.io.IOException; import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequestBuilder; import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse; import org.elasticsearch.action.get.GetRequestBuilder; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.client.Client; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.xcontent.XContentBuilder; public class MyTestClass { private static Client getClient() { ImmutableSettings.Builder settings = ImmutableSettings.settingsBuilder(); TransportClient transportClient = new TransportClient(settings); transportClient = transportClient.addTransportAddress(new InetSocketTransportAddress("localhost", 9300)); return (Client) transportClient; } public static void main(String[] args) throws IOException, InterruptedException { final Client client = getClient(); // Create Index and set settings and mappings final String indexName = "test"; final String documentType = "tweet"; final String documentId = "1"; final String fieldName = "foo"; final String value = "bar"; IndicesExistsResponse res = client.admin().indices().prepareExists(indexName).execute().actionGet(); if (res.isExists()) { DeleteIndexRequestBuilder delIdx = client.admin().indices().prepareDelete(indexName); delIdx.execute().actionGet(); } CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(indexName); // MAPPING GOES HERE // createIndexRequestBuilder.addMapping(documentType, WHATEVER THE MAPPING IS); // MAPPING DONE createIndexRequestBuilder.execute().actionGet(); // Add documents IndexRequestBuilder indexRequestBuilder = client.prepareIndex(indexName, documentType, documentId); // build json object XContentBuilder contentBuilder = jsonBuilder().startObject().prettyPrint(); contentBuilder.field(fieldName, value); indexRequestBuilder.setSource(contentBuilder); indexRequestBuilder.execute().actionGet(); // Get document System.out.println(getValue(client, indexName, documentType, documentId, fieldName)); Thread.sleep(10000L); // Try again System.out.println(getValue(client, indexName, documentType, documentId, fieldName)); } protected static String getValue(final Client client, final String indexName, final String documentType, final String documentId, final String fieldName) { GetRequestBuilder getRequestBuilder = client.prepareGet(indexName, documentType, documentId); getRequestBuilder.setFields(new String[] { fieldName }); GetResponse response2 = getRequestBuilder.execute().actionGet(); String name = response2.getField(fieldName).getValue().toString(); return name; } } 

最后一天的谷歌search得到了回报。 坦率地说,elasticsearch的Java API文档可以使用一些端到端的例子,更不用说JavaDoc了。

这是一个运行的例子。 你必须有一个运行在本地主机上的节点才能工作!

 package foo; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import java.io.IOException; import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequestBuilder; import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse; import org.elasticsearch.action.get.GetRequestBuilder; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.client.Client; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.xcontent.XContentBuilder; public class MyTestClass { private static final String ID_NOT_FOUND = "<ID NOT FOUND>"; private static Client getClient() { final ImmutableSettings.Builder settings = ImmutableSettings.settingsBuilder(); TransportClient transportClient = new TransportClient(settings); transportClient = transportClient.addTransportAddress(new InetSocketTransportAddress("localhost", 9300)); return transportClient; } public static void main(final String[] args) throws IOException, InterruptedException { final Client client = getClient(); // Create Index and set settings and mappings final String indexName = "test"; final String documentType = "tweet"; final String documentId = "1"; final String fieldName = "foo"; final String value = "bar"; final IndicesExistsResponse res = client.admin().indices().prepareExists(indexName).execute().actionGet(); if (res.isExists()) { final DeleteIndexRequestBuilder delIdx = client.admin().indices().prepareDelete(indexName); delIdx.execute().actionGet(); } final CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(indexName); // MAPPING GOES HERE final XContentBuilder mappingBuilder = jsonBuilder().startObject().startObject(documentType) .startObject("_ttl").field("enabled", "true").field("default", "1s").endObject().endObject() .endObject(); System.out.println(mappingBuilder.string()); createIndexRequestBuilder.addMapping(documentType, mappingBuilder); // MAPPING DONE createIndexRequestBuilder.execute().actionGet(); // Add documents final IndexRequestBuilder indexRequestBuilder = client.prepareIndex(indexName, documentType, documentId); // build json object final XContentBuilder contentBuilder = jsonBuilder().startObject().prettyPrint(); contentBuilder.field(fieldName, value); indexRequestBuilder.setSource(contentBuilder); indexRequestBuilder.execute().actionGet(); // Get document System.out.println(getValue(client, indexName, documentType, documentId, fieldName)); int idx = 0; while (true) { Thread.sleep(10000L); idx++; System.out.println(idx * 10 + " seconds passed"); final String name = getValue(client, indexName, documentType, documentId, fieldName); if (ID_NOT_FOUND.equals(name)) { break; } else { // Try again System.out.println(name); } } System.out.println("Document was garbage collected"); } protected static String getValue(final Client client, final String indexName, final String documentType, final String documentId, final String fieldName) { final GetRequestBuilder getRequestBuilder = client.prepareGet(indexName, documentType, documentId); getRequestBuilder.setFields(new String[] { fieldName }); final GetResponse response2 = getRequestBuilder.execute().actionGet(); if (response2.isExists()) { final String name = response2.getField(fieldName).getValue().toString(); return name; } else { return ID_NOT_FOUND; } } } 

我实际上会在这里添加另一个答案,坦率地说,上面的答案给了我的实现一开始,但没有回答实际问题100%(不仅更新根级属性,而且实际领域/属性)。 花了我差不多两天的时间来解决这个问题(文档对于ES Java API来说有点亮)。 我的“映射”类还不是100%,但稍后可以添加更多的字段(“格式”等)。

我希望这可以帮助其他尝试使用更新映射的人!

获取/检索映射

 ImmutableOpenMap<String, ImmutableOpenMap<String, MappingMetaData>> indexMappings = response.getMappings(); ImmutableOpenMap<String, MappingMetaData> typeMappings = indexMappings.get(indexName); MappingMetaData mapping = typeMappings.get(type); Map<String, Mapping> mappingAsMap = new HashMap<>(); try { Object properties = mapping.sourceAsMap().get("properties"); mappingAsMap = (Map<String, Mapping>) gson.fromJson(gson.toJson(properties), _elasticsearch_type_mapping_map_type); return mappingAsMap; } 

更新映射

 PutMappingRequest mappingRequest = new PutMappingRequest(indexName); Map<String, Object> properties = new HashMap<>(); Map<String, Object> mappingsMap = (Map<String, Object>) gson.fromJson(gson.toJson(mapping), Json._obj_map_type); properties.put("properties", mappingsMap); mappingRequest = mappingRequest.ignoreConflicts(true).type(type).source(properties).actionGet(); 

我的GSON映射types

 public static final Type _obj_map_type = new TypeToken<LinkedHashMap<String, Object>>(){}.getType(); public static final Type _elasticsearch_type_mapping_map_type = new TypeToken<LinkedHashMap<String, Mapping>>(){}.getType(); 

我的映射类

 public class Mapping { private String type; private String index; private String analyzer; public String getType() { return type; } public void setType(String type) { this.type = type; } public String getIndex() { return index; } public void setIndex(String index) { this.index = index; } public String getAnalyzer() { return analyzer; } public void setAnalyzer(String analyzer) { this.analyzer = analyzer; } } 

另一种解决scheme是使用称为dynamic模板的function。 这个想法很好地描述在这篇文章中http://joelabrahamsson.com/dynamic-mappings-and-dates-in-elasticsearch/

所以这个例子使用正则expression式来声明任何以tikaprop_开头的字段为Stringtypes。

 curl -XPUT "http://localhost:9200/myindex" -d' { "mappings": { "_default_": { "date_detection": true, "dynamic_templates": [ { "tikaprops": { "match": "tikaprop_.*", "match_pattern": "regex", "mapping": { "type": "string" } } } ] } } }' 

或者您更愿意通过Elasticsearch Java API来完成

 CreateIndexRequestBuilder cirb = this.client.admin().indices().prepareCreate(INDEX_NAME).addMapping("_default_", getIndexFieldMapping()); CreateIndexResponse createIndexResponse = cirb.execute().actionGet(); private String getIndexFieldMapping() { return IOUtils.toString(getClass().getClassLoader().getResourceAsStream("elasticsearch_dynamic_templates_config.json")); } 

使用elasticsearch_dynamic_templates_config.json beein:

 { "date_detection": true, "dynamic_templates": [ { "tikaprops": { "match": "tikaprop_.*", "match_pattern": "regex", "mapping": { "type": "string" } } } ] } 

我从Anders Johansen给出的优秀答案开始,并将其转换为Groovy(以便JSON更易于阅读)。 我与你分享我的答案。

 package com.example import groovy.json.JsonSlurper import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequestBuilder import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse import org.elasticsearch.action.get.GetRequestBuilder import org.elasticsearch.action.get.GetResponse import org.elasticsearch.action.index.IndexRequestBuilder import org.elasticsearch.client.Client import org.elasticsearch.client.transport.TransportClient import org.elasticsearch.common.transport.InetSocketTransportAddress class StackOverflow { Client client; final byte[] ipAddr = [192, 168,33, 10]; // Your ElasticSearch node ip goes here final String indexName = "classifieds"; final String documentType = "job"; public StackOverflow() { client = TransportClient.builder().build() .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByAddress(ipAddr), 9300)); } public void index(){ final IndicesExistsResponse res = client.admin().indices().prepareExists(indexName).execute().actionGet(); if (res.isExists()) { final DeleteIndexRequestBuilder delIdx = client.admin().indices().prepareDelete(indexName); delIdx.execute().actionGet(); } final CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(indexName); // Create Mapping def jsonSlurper = new JsonSlurper() def mapping = jsonSlurper.parseText ''' { "job": { "properties": { "company": { "type": "string", "analyzer": "english" }, "desc": { "type": "string", "analyzer": "english" }, "loc": { "type": "string", "analyzer": "english" }, "req": { "type": "string", "analyzer": "english" }, "title": { "type": "string", "analyzer": "english" }, "url": { "type": "string", "analyzer": "english" } } } }''' System.out.println(mapping.toString()); createIndexRequestBuilder.addMapping(documentType, mapping); // MAPPING DONE createIndexRequestBuilder.execute().actionGet(); // Add documents final IndexRequestBuilder indexRequestBuilder = client.prepareIndex(indexName, documentType, "1"); // build json object def jobcontent = jsonSlurper.parseText ''' { "company": "ACME", "title": "Groovy Developer", "loc": "Puerto Rico", "desc": "Codes in Groovy", "req": "ElasticSearch, Groovy ", "url": "http://stackoverflow.com/questions/22071198/adding-mapping-to-a-type-from-java-how-do-i-do-it#" } ''' indexRequestBuilder.setSource(jobcontent); indexRequestBuilder.execute().actionGet(); } private String getValue2(final String indexName, final String documentType, final String documentId, final String fieldName) { GetRequestBuilder getRequestBuilder = client.prepareGet(indexName, documentType, documentId); getRequestBuilder.setFields([ fieldName ] as String[]); GetResponse response2 = getRequestBuilder.execute().actionGet(); String name = response2.getField(fieldName).getValue().toString(); return name; } public String getValue(final String documentId, final String fieldName){ getValue2(indexName, documentType, documentId, fieldName ) } public void close() { client.close() } public static void main (String[] Args){ StackOverflow so = new StackOverflow(); so.index(); Thread.sleep(5000L); System.out.println(so.getValue("1", "title")); so.close(); } }