Morrowless
Morrowless

Reputation: 6958

Bool should query with filter and nested object

I have sourceString documents that have a nested object targetStrings targetStrings is mapped properly as nested type:

PUT /test-string
{
  "mappings": {
    "properties": {
      "id": { "type": "keyword" },
      "pid": { "type": "keyword" },
      "text": {
        "type": "text"
      },
      "targetStrings": {
        "type": "nested",
        "properties": {
          "pid": { "type": "keyword" },
          "text": {
            "type": "text"
          }
        }
      }
    }
  }
}

Sample docs:

POST test-string/_doc
{
  "id": "1",
  "pid": "someId",
  "text": "lorem",
  "targetStrings": [
    {
      "pid": "someId",
      "text": "ipsum"
    }
  ]
}
POST test-string/_doc
{
  "id": "2",
  "pid": "someId",
  "text": "dolor",
  "targetStrings": [
    {
      "pid": "someId",
      "text": "sit"
    }
  ]
}

If I remove the filter, the search works. But with the filter, I get 2 results, which suggests that it's simply applying the filter and not ANDing it with the should part. This is with Elasticseach version 7.6.

GET test-string/_search
{
  "query": {
    "bool": {
"filter":[
        {"term":{"pid":"someId"}}
      ],
      "should": [
        {
          "match": {
            "text": "lorem"
          }
        },
        {
          "nested": {
            "path": "targetStrings",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "targetStrings.text": "foobar"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

Upvotes: 1

Views: 51

Answers (1)

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

Reputation: 16915

There must me something wrong w/ your mapping that you haven't shared with us.

Here are my replication steps:

Init index w/ nested mapping:

PUT /source-string
{
  "mappings": {
    "dynamic": true,
    "properties": {
      "targetStrings": {
        "type": "nested",
        "properties": {
          "text": {
            "type": "text"
          }
        }
      },
      "text": {
        "type": "text"
      }
    }
  }
}

Index a sample object:

POST source-string/_doc
{
  "text": "foo",
  "targetStrings": [
    {
      "text": "bar"
    },
    {
      "text": "lorem ipsum"
    },
    {
       "text": "NOTAMATCH"
    }
  ]
}

Query your text and nested targetStrings.text:

GET source-string/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "text": "NOTAMATCH"
          }
        },
        {
          "nested": {
            "path": "targetStrings",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "targetStrings.text": "NOTAMATCH"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

which yields exactly 1 hit.


FYI your query had one comma too many at the end of the filter section:

      "filter":[
        {"term":{"pid":"dh9lc4ZLdmZgtYNY0Q9O"}},
        {"term":{"sourceType":"glossary"}},        <--------  
      ],

Edit after the question edit

Move your bool-should inside of the filter to force your "OR" clause inside of an "AND":

GET test-string/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "pid": "someId"
          }
        },
        {
          "bool": {
            "should": [
              {
                "match": {
                  "text": "lorem"
                }
              },
              {
                "nested": {
                  "path": "targetStrings",
                  "query": {
                    "bool": {
                      "must": [
                        {
                          "match": {
                            "targetStrings.text": "foobar"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

Upvotes: 1

Related Questions