Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter nested array in response?

I'm using nested documents in ES. I have nested array inside one entity and I would like to be able to filter array with nested query (not just filter root/parent doc but nested array also).

Nested filters enable to filter root doc. For example, if I have index 'blogs' and type 'blog' and inside blog document I have property 'comments' (array of comments), with {"type": "nested" } in mappings, So for example I want to filter blogs that have comments that have title like 'today' (for example with match query) but in every blog I also want to show only comments that contains 'today' in title.

I know how nested filterworks. Also child-parent relationship isn't good for this purpose because there is no child documents in response as part of parent document.

Is there any way to do this directly in elasticsearch, without adding extra logic to application, which may affect performance ? Or is there and plans to add this as new option in nested query/filter in next versions or something similar ?

Thanks

...add

For instance, have a look at this doc:

 .....
"blogs" :[
    {
         "id":1000,
         "content":"hello world!!!",
         "author:"evan",
         "createTime":"2013-05-31",
          "comments" : [
                   {"author":"jack", id:"1", "content":"test test","createTime":"2013-05-31"},
                   {"author":"tom",  id:"2", "content":"test test","createTime":"2013-05-30"},
                   {"author":"oliver", id:"3", "content":"test test","createTime":"2013-05-30"},
                   {"author":"Jonesie", id:"4", "content":"test test","createTime":"2013-05-29"}
           ]
    },
    {
         "id":1001,
         "content":"test data",
         "author:"jack",
         "createTime":"2013-05-30",
          "comments" : [
                   {"author":"Zach", id:"11", "content":"test data 1","createTime":"2013-05-31"},
                   {"author":"tom",  id:"21", "content":"test data 2","createTime":"2013-05-31"},
                   {"author":"oliver", id:"31", "content":"test test 3","createTime":"2013-05-28"},
                   {"author":"Jonesie", id:"41", "content":"test test 4","createTime":"2013-05-27"}
           ]
    }
]
.....

I would like to run query like:

filter by blogs.createTime == '2013-05-31' and filter blogs.comments.createTime=='2013-05-31'

expect :

 .....
"blogs" :[
    {
         "id":1000
         "content":"hello world!!!",
         "author::"evan",
         "createTime":"2013-05-31"
          "comments" : [
                   {"author":"jack", id:"1", "content":"test test","createTime":"2013-05-31"}
           ]
    } 
]
....

thanks

like image 822
evan Avatar asked Nov 13 '22 04:11

evan


1 Answers

In short: you can't. You need to filter the nested docs in your own code.

It's a known issue:

"Expose matching nested docs to the query and sort" https://github.com/elasticsearch/elasticsearch/issues/1383:

"Return matching nested inner objects per hit."

https://github.com/elasticsearch/elasticsearch/issues/3022

like image 165
Geert-Jan Avatar answered Nov 15 '22 10:11

Geert-Jan