0

The title of the question does not fully justify what I require. I have a nested document in the form

{
    "tags": [
        {
            "context": "context_pic_elements",
            "name": "walls",
            "created_at": 1542806972000,
            "tag_id": 48,
            "tagging_id": 1225
        },
        {
            "context": "element",
            "name": "solo",
            "created_at": 1542806972000,
            "tag_id": 47,
            "tagging_id": 1226
        },
        {
            "context": "end_use",
            "name": "home renovation",
            "created_at": 1542806972000,
            "tag_id": 45,
            "tagging_id": 1224
        }
    ],
    "name": "Wall patterns",
}

The document is mapped against

{
  "properties": {
    "name": {
      "type": "text"
    },
    "tags": {
      "type": "nested",
      "properties": {
        "name": { "type": "keyword" },
        "context": { "type": "keyword" },
        "tag_id": { "type": "integer" }
      }
    }
  }
}

I want to be able to query an image in the form of

images WHERE
    (tags.context="context_pic_elements" AND tags.name="walls")
    OR (tags.context="element" AND tags.name="solo")

The query I am trying right now is

{
  "query": {
    "nested" : {
      "path" : "tags",
      "query": {
        "bool": {
          "should" : {
            "bool": {
              "must": [
                {"term": {"tags.context": "context_pic_elements"}},
                {"term": {"tags.name": "walls"}}
              ]
            }
          }
        }
      }
    }
  }
}

This allows me to query the first condition of the AND clause. Where do I add the second AND condition (Elastic search does not allow more than one must clause in its query) in the query to allow me to query by both conditions. I looked at elasticsearch bool query combine must with OR, but this is not what I require.

Moiz Mansur
  • 174
  • 3
  • 11

1 Answers1

2

Since nested documents are separate documents, you need to do it the other way around, i.e. OR two nested clauses instead of nesting two OR clauses, it goes like this:

POST index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "nested": {
            "path": "tags",
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "tags.context": "context_pic_elements"
                    }
                  },
                  {
                    "term": {
                      "tags.name": "walls"
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "nested": {
            "path": "tags",
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "tags.context": "element"
                    }
                  },
                  {
                    "term": {
                      "tags.name": "solo"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}
Val
  • 165,097
  • 10
  • 260
  • 279