Java: Exact match on nested field

Hi,

until now i had to identify a datastructure by a single sef-url. In my json doc i had:
"sefUrl" : "cat-13"

I had to set sefUrl as not_analyzed. To identify this datastructure with an exact match, i used following code:

final String sefUrl = "cat-13";
final SearchResponse response = getClient().prepareSearch(INDEX)
			.setTypes(TYPE).setSearchType(SearchType.QUERY_THEN_FETCH)
		        .setQuery(QueryBuilders.termQuery("sefUrl", sefUrl))
		        .execute()
		        .actionGet();

That worked fine until i now have the requirement for a multilanguage support on the sefUrl which i realized with a HashMap. In my json doc now i have:
"sefUrlMap" : {
"en" : "encat-13",
"de" : "cat-13"
}

How can i now do an exact match on this map to identify this datastructure?

With kind regards
David

Now i defined the nested map as not_analyzed and the mapping looks like:

"sefUrlMap": {
	"type": "nested",
	"properties": {
		"de": {
			"type": "string",
			"index": "not_analyzed"
		},
		"en": {
			"type": "string",
			"index": "not_analyzed"
		}
	}
}

and i use the nestedquery:

final String sefUrl = "cat-13";
final SearchResponse response =  _elasticSearchClient.getClient().prepareSearch(INDEX)
	.setTypes(TYPE).setSearchType(SearchType.QUERY_THEN_FETCH)
        .setQuery(QueryBuilders.nestedQuery("sefUrlMap", QueryBuilders.termQuery("de", sefUrl)))
        .execute()
        .actionGet();

But i still don't get any results.

What am i doing wrong?

Kind regards
David

on i've kicked the nested type from my mapping and replaced it with the object type and use my termquery from before and access the inner field with the dot notation and it works


this i can read 100 times, i can not understand when to use object and when to use nested

You need to specify the full path in the query

.setQuery(QueryBuilders.nestedQuery("sefUrlMap", QueryBuilders.termQuery("sefUrlMap.de", sefUrl)))

See https://www.elastic.co/guide/en/elasticsearch/guide/2.x/nested-query.html for more info.

However, using a nested type here looks like an overkill. It will be more efficient to implement it by using a standard object:

"sefUrlMap": {
	"type": "object",
	"properties": {
		"de": {
			"type": "string",
			"index": "not_analyzed"
		},
		"en": {
			"type": "string",
			"index": "not_analyzed"
		}
	}
}

and

.setQuery(QueryBuilders.termQuery("sefUrlMap.de", sefUrl))

Nested objects are typically used, when there is an array of such objects and you need to preserve relationship between fields within an object. Like in case of make and model in the example from the guide. If you have only one instance of an object, there is no relationship and therefore there is no need to use nested.

aaahhh,

when using the nested type i must specify the full path in the TERM query... that was not clear to me.

yeah, your 2nd is exactly what i do now.

thanks for clarification on the nested objects