Nested query and empty results

Hi all,

I'm starting to use ES and I struggle with the concept of nested queries. I would like to filter nested comment of my blog post respecting the following condition

  • Only nested elements which respect query are returned
  • If there are no nested results, the parent must be returned.

The goal is to return all posts without their unvalidated comments.

My mapping

{  
   "post":{  
      "mappings":{  
         "post":{  
            "properties":{  
               "id":{  
                  "type":"integer"
               },
               "comments":{  
                  "type":"nested",
                  "include_in_parent":true,
                  "properties":{  
                     "content":{  
                        "type":"text"
                     },
                     "is_valid":{  
                        "type":"integer",
                     }
                  }
               }
            }
         }
      }
   }
}

Current documents

{
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "hits": {
    "total": 3,
    "max_score": 1,
    "hits": [
      {
        "_type": "post",
        "_id": "1",
        "_score": 1,
        "_routing": "1",
        "_source": {
          "id": "1",
          "comments": [
            {
              "id": "1",
              "content": "Lorem ipsum dolor sit amet.",
              "is_valid" : 1
            },
            {
              "id": "2",
              "content": "Lorem ipsum dolor sit amet.",
              "is_valid" : 0
            },
          ]
        },
        {
          "id": "2",
          "comments": [
            {
              "id": "3",
              "content": "Lorem ipsum dolor sit amet.",
              "is_valid" : 0
            }
          ]
        },
        {
          "id": "3",
        },
      }
    ]
  }
}

Current query

GET _search
{
  "query": {
    "bool": {
      "should": [
        {
          "nested": {
            "path": "comments",
            "query": {
                 "match" : { "comments.is_valid" : 1 }

            },
            "inner_hits": {}
          }
        },
        {
          "bool": {
            "must_not": {
              "exists": {
                "field": "comments"
              }
            }
          }
        }
      ]
    }
  }
}

So with this query, I can retrieve post#1 without invalid comments in his inner_hits field and post#3 cause he has no comments.

But I don't know how to get post#2, he has only one invalid comment and this query doesn't match.

How can I fix this?

Thanks :slight_smile:

What is it exactly that you want the query to return? All posts that have at least 1 invalid comment or no comments at all??

Ideally this

{
  "hits": {
    "total": 3,
    "max_score": 1,
    "hits": [
      {
        "_source": {
          "id": "1",
          "comments": [
            {
              "id": "1",
              "content": "Lorem ipsum dolor sit amet",
              "is_valid" : 1
            },
          ]
        }
      },
      {
        "_source": {
          "id": "2"
        }
      },
      {
        "_source": {
          "id": "3",
      },
    ]
  }
}

I want to get all posts, regardless they have comments or not. And if they had, only valid ones will be returned.

Sorry for the late reply. But i think what you need to do is use two nested queries:

GET /indexname/_search
{
  "size":0,
  "query":{
    "bool":{
      "should": [
        {
          "nested":{
            #condition 1
          }
        },
        {
          "nested":{
            #condition 2
          }
        }
      ]
    }
  }
}

I am not 100% sure why the query format you used doesn't work, maybe someone on the Elastic Team can reply to the thread, I tried using your format and it surely doesn't work. But the one I provided works for me, let me know if this solves your issue.

Sorry for the late reply.

Thanks.

Hi,
Thx for your answer

I tried with 2 nested queries, But I'm not able to get post#2 without his invalid comments, or I miss something.

Basically, the question is, can nested query filter doc's children without impact their parents?
If my nested query returns no result, can I still get the parent?

Maybe I'm trying to achieve something that ES is not designed for. ^^

So you have 3 different kinds of nested documents that you want the query to return. Have you tried using 3 nested queries inside the should block(each nested block would return one kind of document that you want the query to return)...