Nested field query using elastic4s on ElasticSearch
I want to request a subdocument indexed in ES.
For example, a nested field user
that contains two fields id
and name
. I want to query all documents where the name exactly matches the field user.name
.
Can't figure out how to use DSL for elastic disks.
This is how you do nested queries in elastic4s:
First of all, set up the index so that you have a nested type:
client.execute {
create index "nested" mappings {
"show" as {
"actor" typed NestedType
}
}
}
Then with some sample data
client.execute(
index into "nested/show" fields(
"name" -> "game of thrones",
"actor" -> Seq(
Map("name" -> "peter dinklage", "birthplace" -> "Morristown"),
Map("name" -> "pedro pascal", "birthplace" -> "Santiago")
)
)
)
Then comes the key part. To search, you used nested
(or in beta4 beta 1.4, nestedQuery
) to "insert" into a nested scope, where you can search using any standard query type. Here I am just using a simple search termQuery
.
client.execute {
search in "nested/show" query nested("actor").query(termQuery("actor.name" -> "dinklage"))
}
What about:
clientProvider.getClient.execute {
(search in path)
.query(
nested("[something].user").query(
bool(must(
term("something.user.name" -> name)
))
)
)
}
Since I am not familiar with your structure, I have provided my own example and perhaps you could from there:
- The storage location consists of metadata about the venue and venue.
- collected a list of employees, which is nested ()
- employee got an identifier of type Long
def venueByEmployeeId(employeeId: Long): Future[Option[VenueData]] = {
clientProvider.getClient.execute {
(search in path)
.query(
nested("venue.employees").query(
bool(must(
term("venue.employees.id" -> employeeId)
))
)
)
}.map(_.getHits.jsonToList[VenueData].headOption)
}
What I forgot about the request is that you have to write the entire path ("Meeting place .employees.id" -> employeeId)