【问题标题】:Adding mapping to a type from Java - how do I do it?从 Java 向类型添加映射 - 我该怎么做?
【发布时间】:2014-03-31 00:58:38
【问题描述】:

我正在尝试或多或少地使用 Java API 重新创建 this example

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

请告诉我如何在 Java 中创建 the equivalent of this from the example in the documentation 的映射:

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;
    }

}

【问题讨论】:

    标签: java elasticsearch


    【解决方案1】:

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

    这是一个正在运行的示例。您必须在 localhost 上运行一个节点才能使其正常工作!

    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;
            }
        }
    
    }
    

    【讨论】:

    • 是的,文档有点轻,不是吗?感谢您解决这个问题。
    • 这非常接近我所需要的...除了我还需要能够将映射添加到已经存在的索引。有人吗?
    • 我想我发现了如何做到这一点。而不是 prepareCreate 你使用 preparePutMapping: PutMappingResponse response = client.admin().indices() .preparePutMapping(index) .setType(type) .setSource(mappingBuilder) .execute().actionGet();
    • 我想更新已经存在的映射,但我看到它没有发生代码:PutMappingResponse response = client.admin().indices() .preparePutMapping(index) .setType(type) .setSource( mappingBuilder) .execute().actionGet();
    • JavaDocs for 2.3.0 : javadoc.io/doc/org.elasticsearch/elasticsearch/2.3.0 您也可以选择下拉菜单转到任何其他版本。
    【解决方案2】:

    我实际上要在此处添加另一个答案,因为坦率地说,上述答案为我的实施提供了一个开始,但没有 100% 回答实际问题(不仅更新根级别属性,还更新 ACTUAL 字段/属性)。我花了将近 2 天的时间才弄清楚这一点(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 映射类型

    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;
        }
    }
    

    【讨论】:

      【解决方案3】:

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

      所以本例使用正则表达式声明任何以 tikaprop_ 开头的字段为字符串类型。

      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 蜜蜂:

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

      【讨论】:

        【解决方案4】:

        我从 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();
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-01-26
          • 1970-01-01
          • 2018-01-16
          • 1970-01-01
          • 2022-12-06
          • 2013-10-16
          • 2012-05-20
          相关资源
          最近更新 更多