I wish to implement the following rest api:
POST /t_source_item/_search?typed_keys=true&search_type=query_then_fetch
{
"query": {
"bool": {
"filter": [
{
"term": {
"tags.id": {
"value": "1"
}
}
},
{
"term": {
"tags.id": {
"value": "2"
}
}
}
]
}
}
}
Below is the code I wrote:
import org.springframework.data.elasticsearch.client.elc.NativeQuery
val query = NativeQuery.builder().withQuery { q1 ->
q1.bool { b ->
b.filter { q2 ->
q2.term { tq ->
listOf(1L, 2L).forEach { t ->
tq.field("tags.id").value(t)
}
tq
}
}
}
}.build()
val searchHits = elasticsearchOperations.search(query, Book::class.java)
But I always only get the last term
instead of multiple term
, the rest api results are as follows:
{
"query": {
"bool": {
"filter": [
{
"term": {
"tags.id": {
"value": 2
}
}
}
]
}
}
}
What should be the correct approach? I am using spring-data-elasticsearch:5.0.3
.
You are using the forEach
with the tag ids to set the id of the same term query, that's why you see only the last value that was set.
You must use the loop to create separate filter queries:
val query = NativeQuery.builder().withQuery { q1 ->
q1.bool { b ->
listOf(1L, 2L).forEach { t ->
b.filter { q2 ->
q2.term { tq ->
tq.field("tags.id").value(t)
tq
}
}
}
b
}
}.build()
alternate version using a range instead of a listOf:
val query = NativeQuery.builder().withQuery { q1 ->
q1.bool { b ->
for (t in 1L..2L) {
b.filter { q2 ->
q2.term { tq ->
tq.field("tags.id").value(t)
tq
}
}
}
b
}
}.build()