I am trying to recreate this example using the Java API more or less.
I think all I need is to add a mapping to the index, but the Java API docs are not exactly clear on how to do this.
Please tell me how I create a mapping in Java that is 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" } } }'
Here's my 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; } }
HashMap put() Method in Java HashMap. put() method of HashMap is used to insert a mapping into a map. This means we can insert a specific key and the value it is mapping to into a particular map. If an existing key is passed then the previous value gets replaced by the new value.
A Map is an object that maps keys to values. A map cannot contain duplicate keys: Each key can map to at most one value. It models the mathematical function abstraction.
A map is a data structure that's designed for fast lookups. Data is stored in key-value pairs with every key being unique. Each key maps to a value hence the name. These pairs are called map entries.
To make a map, place 8 papers and 1 compass on Java Edition (PC/Mac), Xbox and PS in the 3x3 crafting grid. In PE and Windows 10, you need 9 papers to make a map.
Finally a day of googling paid off. Frankly the Java API docs for elasticsearch could use some end-to-end examples, not to mention JavaDoc...
Here's a running example. You must have a node running on localhost for this to work!
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; } } }
I am actually going to add another answer here because frankly speaking, the above answers gave a start to my implementation but didn't answer the actual question 100% (updating not just the root level properties, but the ACTUAL field/properties). Took me almost 2 days to figure this out (Documentation is a bit light for ES Java APIs). My "Mapping" class is not 100% yet, but more fields could be added to it ("format" etc) later.
I hope this helps everyone else who is trying to use update mappings!
GET/RETRIEVE MAPPINGS
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; }
UPDATE MAPPINGS
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();
My GSON mapping 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();
My Mapping Class
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; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With