Soumya Simanta
Soumya Simanta

Reputation: 11741

Query on a nested field using elastic4s on ElasticSearch

I want to query a nested document that is indexed in ES.

For example, the nested field is user which contains two fields id and name. I want to query all documents where the name exactly matches the field user.name.

Cannot figure out how to use the elastic4s DSL for that.

Upvotes: 4

Views: 2660

Answers (2)

jakob
jakob

Reputation: 5995

How about:

clientProvider.getClient.execute {
    (search in path)
      .query(
        nested("[something].user").query(
        bool(must(
          term("something.user.name" -> name)
        ))
        )
      )
    }

Since I'm not familiar with your structure i will provide my own example and maybe you could go from there:

  • venueData consist of meta data about a venue and the venue itself.
  • venue got a list of employees that is a NestedType nested()
  • employee got an id that is 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)
}

The thing I did forget about the query is that you need to write the entire path term("venue.employees.id" -> employeeId)

Upvotes: 2

sksamuel
sksamuel

Reputation: 16387

This is how you do nested queries in elastic4s:

First of all, setting up the index such 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 the key part. To search, you used the nested (or in elastic4s 1.4 beta, nestedQuery) to "drop into" the nested scope, where you can search using any standard query type. Here I am just using a simple termQuery search.

client.execute {
  search in "nested/show" query nested("actor").query(termQuery("actor.name" -> "dinklage"))
}

Upvotes: 4

Related Questions