I am using spring-data-elasticsearch. I have constructed most of the query conditions using criteria with lots of sub-criteria. Now I want to include a simple query condition for a nested field. But criteria corms query using uery_string API which is not working for nested fields. I am expecting Nested query.
How to support this using Criteria without NativeSearchQuery?
Nested Mapping
{
"ae": {
"type": "nested",
"properties": {
"atb": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"su": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
I want to query "ae.su.keyword" field. Building criteriaQuery using this field constructs query_string query using this field, which is not returing correct documents in response as expected. My expectationis, Is there any way to build nested query using criteria? or Override existing criteria query?
Criteria criteria = new Criteria("ae.su.keyword").is("VALUE");
CriteriaQuery query = new CriteriaQuery(criteria);
elasticOperations.search(query, Foo.class, index);
Currently Spring Data Elasticsearch's CriteriaQuery
does not support creating nested queries.
The query that is created currently with your example code is (cleaning out irrelevant parts):
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "one",
"fields": [
"ae.su.keyword^1.0"
]
}
}
]
}
}
}
With the nested object you have the needed query would be:
{
"query": {
"nested": {
"path": "ae",
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "one",
"fields": [
"ae.su.keyword"
]
}
}
]
}
}
}
}
}
basically wrapping the query that is built now in an additional nested query.
As I wrote, creating this nested query is not supported at the moment. What you can do, besides building a
NativeSearchQuery
, is using a StringQuery
(yes, it's very ugly as well):
Query query = new StringQuery("{\"nested\":{\"path\":\"ae\",#" +
"\"query\":{\"bool\":{\"must\":[{\"query_string\": {\"query\":\"$1\"," +
"\"fields\":[\"ae.su.keyword\"]}}]}}}}".replace("$1", value));
return operations.search(query, Foo.class);
Edit 01.04.2021:
This topic came up again in an issue, I opened a bug issue to address this. I will go to implement this fix these days.
Edit 05.04.2021:
fixed from 4.2.0.GA on