I have a few elasticsearch fields that I don\'t want to analyze before indexing. I have read that the right way to do this is by altering the index mapping. Right now my map
Adding this for future readers. Please note you need to perform mapping prior to create the actual index or you will get an exception. See following code.
client.admin().indices().create(new CreateIndexRequest("indexname")).actionGet();
PutMappingResponse putMappingResponse = client.admin().indices()
.preparePutMapping("indexname")
.setType("indextype")
.setSource(jsonBuilder().prettyPrint()
.startObject()
.startObject("indextype")
.startObject("properties")
.startObject("country").field("type", "string").field("index", "not_analyzed").endObject()
.endObject()
.endObject()
.endObject())
.execute().actionGet();
IndexResponse response1 = client.prepareIndex("indexname", "indextype")
.setSource(buildIndex())
.execute()
.actionGet();
// Now "Sri Lanka" considered to be a single country :)
SearchResponse response = client.prepareSearch("indexname"
).addAggregation(AggregationBuilders.terms("countryfacet").field("country")).setSize(30).execute().actionGet();
So, turns out elasticsearch docs are way outdated on that topic. not_analyzed does not exist anymore and string is now text. After some trial and error I came up with this:
CreateIndexRequest createIndexRequest = new CreateIndexRequest("yourIndexName");
XContentBuilder mapping = jsonBuilder()
.startObject()
.startObject("properties")
.startObject("yourProperty")
.field("type", "keyword")
.endObject()
.endObject()
.endObject();
createIndexRequest.mapping("yourEntityName", mapping);
client.indices().create(createIndexRequest);
Now yourProperty can be queried for exact value only with term query.
Just read the Definitive Guide carefully:
Although you can add to an existing mapping, you can’t change existing field mappings. If a mapping already exists for a field, data from that field has probably been indexed. If you were to change the field mapping, the indexed data would be wrong and would not be properly searchable.
Source: https://www.elastic.co/guide/en/elasticsearch/guide/current/mapping-intro.html#updating-a-mapping
So you just have to do it when you create the field. Thats why the code from this answer works without problems.
I have successfully applied mappings to an Elasticsearch index using the Java API like the following:
XContentBuilder mapping = jsonBuilder()
.startObject()
.startObject("general")
.startObject("properties")
.startObject("message")
.field("type", "string")
.field("index", "not_analyzed")
.endObject()
.startObject("source")
.field("type","string")
.endObject()
.endObject()
.endObject()
.endObject();
PutMappingResponse putMappingResponse = client.admin().indices()
.preparePutMapping("test")
.setType("general")
.setSource(mapping)
.execute().actionGet();
Hope this helps.