Please find attached a solution for your problem, described on a working code sample. I had issues using a Terms filter in ElasticSearch. The field indexrecord_uuid contains a UUID String value (e.g. 8457964d-72e4-4b96-9232-c0e90fccd57d) which did not properly respond to exact matching queries using the TermsFilterBuilder.
By calling the Elastcisearch analyzer API I found out that the structure of this is field ist not a single String, but gets split up into multiple tokens. The issue is described here in detail.
GET /_analyze?analyzer=standard
{
"8457964d-72e4-4b96-9232-c0e90fccd57d"
}
Returns the result:
{
"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
}
]
}
So to enable a query like this
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"
}
}]
}
}
}
I had to delete the index and update the field mapping and set it to not_analyzed.
{
"backup" : {
"properties" : {
"indexrecord_uuid" : {
"type" : "string",
"index" : "not_analyzed"
}
}
}
}
issue the 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 in place already is configured to use this mapping configuration you can do by 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;
}