web-dev-qa-db-fra.com

Ajout d'un mappage à un type de Java - comment faire?

J'essaie de recréer cet exemple en utilisant plus ou moins l'API Java API).

Je pense que tout ce dont j'ai besoin est d'ajouter un mappage à l'index, mais les documents de l'API Java API ne sont pas exactement clairs sur la façon de procéder.

Veuillez me dire comment je crée un mappage en Java c'est-à-dire l'équivalent de cela dans l'exemple de la documentation :

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

Voici mon code:

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

}
42
Anders Johansen

Enfin, une journée de recherche sur Google a porté ses fruits. Franchement, les docs Java API pour elasticsearch pourraient utiliser des exemples de bout en bout, sans parler de JavaDoc ...

Voici un exemple courant. Vous devez avoir un nœud en cours d'exécution sur localhost pour que cela fonctionne!

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

}
75
Anders Johansen

Je vais en fait ajouter une autre réponse ici parce que franchement, les réponses ci-dessus ont donné un début à ma mise en œuvre mais n'ont pas répondu à la question réelle à 100% (mise à jour non seulement des propriétés de niveau racine, mais du champ/des propriétés ACTUAL). Cela m'a pris près de 2 jours pour comprendre cela (la documentation est un peu légère pour ES Java). Ma classe "Mapping" n'est pas encore à 100%, mais d'autres champs pourraient y être ajoutés ( "format" etc) plus tard.

J'espère que cela aide tous ceux qui essaient d'utiliser des mappages de mise à jour!

OBTENIR/RECUPERER LES CARTOGRAPHIES

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

MISE À JOUR DES MAPPAGES

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();

Mes types de mappage 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();

Ma classe de cartographie

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

Une solution alternative serait d'utiliser une fonctionnalité appelée modèles dynamiques. L'idée est très bien décrite dans cet article http://joelabrahamsson.com/dynamic-mappings-and-dates-in-elasticsearch/

Donc, ce cas utilise une expression régulière déclarant tout champ commençant par tikaprop_ comme étant de type String.

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

ou si vous préférez le faire via 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"));
}

avec elasticsearch_dynamic_templates_config.json beein:

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

J'ai commencé par l'excellente réponse donnée par Anders Johansen et je l'ai convertie en Groovy (pour que le JSON soit plus facile à lire). Je partage avec vous ma réponse.

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();
    }
}
2
Yamir Encarnacion