Imagine the following documents:
[
{ "name" : "deepgreen", "colors" : [
{ "color" : "green" },
{ "color" : "black" }
]
},
{ "name" : "lightblue", "colors" : [
{ "color" : "blue" },
{ "color" : "white" }
]
},
{ "name" : "purple", "colors": [
{ "color" : "red" },
{ "color" : "blue" },
{ "color" : "white" }
]
}
]
Where the colors
field is of type nested object
, this mapping is correct. The query I would execute to get, for instance, purple, is:
GET /colors/_search
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "colors",
"query": {
"match_phrase": {
"colors.color": "blue"
}
}
}
},
{
"nested": {
"path": "colors",
"query": {
"match_phrase": {
"colors.color": "blue"
}
}
}
},
{
"nested": {
"path": "colors",
"query": {
"match_phrase": {
"colors.color": "blue"
}
}
}
},
{
"match_phrase": {
"name": "purple"
}
}
]
}
}
}
How could I dynamically generate this query using the ES Java API? What I'm trying to do can be understood by looking at this pseudo-code:
List<QueryBuilders> nestedQueryBuilders = new ArrayList<>();
colors.forEach(color -> {
nestedQueryBuilders.add(new nestedQuery("colors",
matchPhraseQuery("colors.color", color)),
ScoreMode.Avg);
});
BoolQueryBuilder boolQuery = boolQuery()
.must(matchPhraseQuery("name", "purple"))
.must(nestedQueryBuilders);
SearchRequest request = new SearchRequest()
.indices("colors")
.source(new SearchSourceBuilder()
.query(boolQuery));
client.search(request, RequestOptions.DEFAULT);
I have not encountered a method yet for adding "sub"-queries to a must-bool-query dynamically.
Anyone have some experience on this and could tell me how to accomplish this?