Add type mapping using JSON schema and Java ElasticSearch API

Is it possible to add a type mappingto ElasticSearch Indexusing the Java API using a schema JSON?

I know that ElasticSearch uses the first document to create mapping, and so I could improve my first document using a schema JSON. But I want to create types before indexing the document.

+4
source share
4 answers

You can do something like:

String mapping = XContentFactory.jsonBuilder().startObject().startObject(typeName).startObject("properties")
                    .startObject("location").field("type", "geo_point").endObject()
                    .startObject("language").field("type", "string").field("index", "not_analyzed").endObject()
                    .startObject("user").startObject("properties").startObject("screen_name").field("type", "string").field("index", "not_analyzed").endObject().endObject().endObject()
                    .startObject("mention").startObject("properties").startObject("screen_name").field("type", "string").field("index", "not_analyzed").endObject().endObject().endObject()
                    .startObject("in_reply").startObject("properties").startObject("user_screen_name").field("type", "string").field("index", "not_analyzed").endObject().endObject().endObject()
                    .startObject("retweet").startObject("properties").startObject("user_screen_name").field("type", "string").field("index", "not_analyzed").endObject().endObject().endObject()
                    .endObject().endObject().endObject().string();
client.admin().indices().preparePutMapping(indexName).setType(typeName).setSource(mapping).execute().actionGet();

Or, if you have a string match

String json = "{}";
PutMappingResponse response = client.admin().indices()
                    .preparePutMapping(index)
                    .setType(type)
                    .setSource(json)
                    .execute().actionGet();     
+5
source

You can use elasticsearch json mapping using java api,

1) Elasticsearch json ,

. resources/Customer.json

{
    "Customer": {
        "settings": {}, 
        "properties": { 
            "name": { "type":"String" , "index": "not_analyzed"}
        }
    }
}

STEP 2) java- json (. )

class EsUtils {

  public static Client client

  public static void applyMapping(String index, String type, String location) throws Exception {

            String source = readJsonDefn(location);

            if (source != null) {
                PutMappingRequestBuilder pmrb = client.admin().indices()
                                                      .preparePutMapping(index)
                                                      .setType(type);
                pmrb.setSource(source);
                MappingListener mappingListener = new MappingListener(pmrb)

                // Create type and mapping
                Thread thread = new Thread(mappingListener)

                thread.start();
                while (!mappingListener.processComplete.get()) {
                    System.out.println("not complete yet. Waiting for 100 ms")
                    Thread.sleep(100);

                }

            } else {
                   System.out.println("mapping error");
            }

       }

       public static String readJsonDefn(String url) throws Exception {
              //implement it the way you like 
              StringBuffer bufferJSON = new StringBuffer();

              FileInputStream input = new FileInputStream(new File(url).absolutePath);
              DataInputStream inputStream = new DataInputStream(input);
              BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));

              String line;

              while ((line = br.readLine()) != null) {
                             bufferJSON.append(line);
              }
              br.close();
              return bufferJSON.toString();
       }

    //runnable mapping listener
    static class MappingListener implements Runnable {
      PutMappingRequestBuilder requestBuilder;
      public AtomicBoolean processComplete;
      PutMappingActionListener actionListener;

      @Override
      void run() {
        try {
            requestBuilder.execute(actionListener)
        } catch (Exception e) {
            e.printStackTrace()
            this.processComplete.set(true)
        }
      }

      public MappingListener(PutMappingRequestBuilder requestBuilder) {
        this.processComplete = new AtomicBoolean(false);
        actionListener = new PutMappingActionListener(processComplete);
        this.requestBuilder = requestBuilder;
      }

     //action listener
     static class PutMappingActionListener implements ActionListener<PutMappingResponse> {
        public AtomicBoolean processComplete;

        public PutMappingActionListener(AtomicBoolean processComplete) {
            this.processComplete = processComplete;
        }

        void onResponse(PutMappingResponse response) {
            if (response.isAcknowledged()) {
                System.out.println("template successfully applied")
            }
            processComplete.set(true)
        }

        @Override
        void onFailure(Throwable throwable) {
            System.out.println("error applying mapping : " + throwable)
            throwable.printStackTrace()
            processComplete.set(true)
        }
      }
     } //end of mappinglistener

    }

3) applyMapping() , es,

String index = "yourIndex"; //yourIndex
String type  = "Customer";
String location = "resources/Customer.json";

EsUtils.client = esClient; //pass your client
EsUtils.applyMapping(index, type, location);

4), ,

SearchRequestBuilder builder = client.prepareSearch("yourIndex");
builder.addAggregation(AggregationBuilders.terms("nameterms")
                                          .field("name").size(0))
SearchResponse response = builder.execute().actionGet();

Elasticsearch

Elasticsearch "not_analyzed" Java

+2

, , MappingListener.

import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;

public class MyElasticSearchService {

  private static final String INDEX = "myIndex";

  private Client client;

  private JsonSchema jsonSchema;

  ... 

  public void createIndexAndTypes() {
    createIndex();
    createType(TYPE_FOO, this.jsonSchema.getFooSchema());
    createType(TYPE_BAR, this.jsonSchema.getBarSchema());
  }

  private void createType(final String type, final String schema) {
    final PutMappingRequestBuilder requestBuilder = this.client.admin().indices().preparePutMapping(INDEX).setType(type);
    final PutMappingResponse response = requestBuilder.setSource(schema).execute().actionGet();
  }
}



import lombok.Getter;

@Getter
public class JsonSchema {

  private String fooSchema;
  private String barSchema;

  public JsonSchema() {
    this.fooSchema = ClasspathUtil.getTextfileContent("foo_schema.json");
    this.barSchema = ClasspathUtil.getTextfileContent("bar_schema.json");
  }
}



import java.io.IOException;

import org.apache.commons.io.IOUtils;
import org.springframework.core.io.ClassPathResource;

public class ClasspathUtil {

    public static String getTextfileContent(final String filename) {
        try {
            return IOUtils.toString(new ClassPathResource(filename).getInputStream());
        } catch (final IOException e) {
            throw new IllegalStateException(e);
        }
    }
}
+1

, , . ElasticSearch. indexrecord_uuid UUID (, 8457964d-72e4-4b96-9232-c0e90fccd57d), TermFilterBuilder.

API- Elastcisearch, , ist , . .

    GET /_analyze?analyzer=standard
{
  "8457964d-72e4-4b96-9232-c0e90fccd57d"
}

:

{
   "tokens": [
      {
         "token": "8457964d",
         "start_offset": 5,
         "end_offset": 13,
         "type": "<ALPHANUM>",
         "position": 1
      },
      {
         "token": "72e4",
         "start_offset": 14,
         "end_offset": 18,
         "type": "<ALPHANUM>",
         "position": 2
      },
      {
         "token": "4b96",
         "start_offset": 19,
         "end_offset": 23,
         "type": "<ALPHANUM>",
         "position": 3
      },
      {
         "token": "9232",
         "start_offset": 24,
         "end_offset": 28,
         "type": "<NUM>",
         "position": 4
      },
      {
         "token": "c0e90fccd57d",
         "start_offset": 29,
         "end_offset": 41,
         "type": "<ALPHANUM>",
         "position": 5
      }
   ]
}

,

    GET /backmeup/backup/_search?pretty
{
  "query": {
    "bool" : {
    "must" : [ {
      "match" : {
        "owner_id" : {
          "query" : "2",
          "type" : "boolean"
        }
      }
    },{
      "bool" : {
        "should" : {
          "bool" : {
            "must" : {
              "filtered" : {
                "query" : {
                  "match_all" : { }
                },
                "filter" : {
                  "terms" : {
                    "indexrecord_uuid" : [ "8457964d-72e4-4b96-9232-c0e90fccd57d"]
                  }
                }
              }
            }
          }
        },
        "minimum_should_match" : "1"
      }
    }]
  }
  }
}

not_analyzed.

{
"backup" : {
     "properties" : {
         "indexrecord_uuid" : {
             "type" : "string",
             "index" : "not_analyzed" 
         }
     }
 }
}

PutMappingRequest

PutMappingRequestBuilder pmrb = this.client.admin().indices().preparePutMapping(INDEX_NAME)
                .setType("backup");
        pmrb.setSource(this.getIndexCustomFieldMapping());
        PutMappingResponse putMappingResponse = pmrb.execute().actionGet();
        if (!putMappingResponse.isAcknowledged()) {
            this.logger.error("Could not create index [" + INDEX_NAME + " ].");
        } else {
            this.logger.debug("Successfully created index [" + INDEX_NAME + " ].");
        }

To check if the existing version of the index is already configured to use this mapping configuration, you can do this

 /**
 * Checks if the currently existing version of the index was configured properly e.g. if the indexrecord_uuid field
 * mapping was set etc
 * 
 * check if the field mapping for indexrecord_uuid was set to not analyzed as this causes issues using the terms
 * filter on UUID Strings https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_exact_values.html
 * https://www.elastic.co/guide/en/elasticsearch/guide/current/analysis-intro.html#analyze-api
 * https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_exact_values.html
 */
private boolean checkIsIndexFieldMappingSet() {
    GetMappingsResponse mapping = this.client.admin().indices().prepareGetMappings(INDEX_NAME).get();
    try {
        HashMap props = (HashMap) mapping.getMappings().get(INDEX_NAME).get("backup").getSourceAsMap();
        if (props != null) {
            if (props.containsKey("properties")) {
                HashMap fieldMappings = ((HashMap) props.get("properties"));
                //check if the field mapping for indexrecord_uuid was set to not analyzed 
                if (fieldMappings.containsKey("indexrecord_uuid")) {
                    HashMap fieldIndexRecordMapping = (HashMap) fieldMappings.get("indexrecord_uuid");
                    if (fieldIndexRecordMapping.containsKey("index")
                            && fieldIndexRecordMapping.get("index").toString().equals("not_analyzed")) {
                        return true;
                    }
                }

            }
        }
    } catch (Exception e) {
        this.logger.debug("Index does not contain a 'not_analyzed' field mapping for indexrecord_uuid");
    }
    return false;
}
0
source

All Articles