Ali Khosro
Ali Khosro

Reputation: 1820

how to filter Elasticsearch by object value field

Our table has a nested map roles like this:

{group: 123, roles: {boss: department1, manager: department2}}

Now I want to find all documents in group 123 who has a role in department1. How can I filter based on the value field of the nested map? Something like:

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "group": "123"
          }
        },
        {
          "nested": {
            "path": "roles",
            "query": {
              "match": {
                "roles.???": "department1"
              }
            }
          }
        }
      ]
    }
  }
}

I know how to filter by nested object keys but could not find out filtering by "object value".

Upvotes: 1

Views: 292

Answers (1)

Joe - Check out my books
Joe - Check out my books

Reputation: 16925

Inspired by this answer, you can script your way to a solution:

{
  "min_score": 0.1,
  "query": {
    "function_score": {
      "query": {
        "match": {
          "group": "123"
        }
      },
      "functions": [
        {
          "script_score": {
            "script": {
              "source": """
                for (def role : params["_source"]["roles"].values()) {
                  if (role == params.role) {
                    return 1
                  }
                }
                
                return 0;
              """,
              "params": {
                "role": "department1"
              }
            }
          }
        }
      ]
    }
  }
}

Beware of the inefficiencies of scripting though -- it may get really slow.

I'd instead advise to rethink your structure -- keep the nested-ness but go with

{
  "group": 123,
  "roles": [
    {
      "position": "manager",
      "department": "department1"
    },
    {
      "position": "boss",
      "department": "department2"
    }
  ]
}

Upvotes: 1

Related Questions