简体   繁体   中英

Solr query NOT on nested child documents

How can I query for parent documents, with child documents NOT having a certain field value?

Eg: Let's say we have the following data structure:

    {
        "type_s": "book",
        "id_l": 4294967298,
        "title_s": "The Little Mermaid"
        {
            "type_s": "review",
            "id_l": "4294967451",       
            "reviewer_s": "Freeman, Gordon",        
            "comment_s": "Great book!"      
        },
        {
            "type_s": "review",
            "id_l": "4294967452",       
            "reviewer_s": "Denton, J.C.",       
            "comment_s": "My daughter loved it!"        
        }
    },
{
        "type_s": "book",
        "id_l": 4294967298,
        "title_s": "Lion King"
        {
            "type_s": "review",
            "id_l": "4294967457",       
            "reviewer_s": "Woods, Susanne",     
            "comment_s": "One of the best!"     
        },
        {
            "type_s": "review",
            "id_l": "4294967458",       
            "reviewer_s": "Denver, Michel",     
            "comment_s": "Liked the ending!"        
        }
    },
    {
        "type_s": "book",
        "id_l": 4294967298,
        "title_s": "7 dwarves"
        {
            "type_s": "review",
            "id_l": "4294967453",       
            "reviewer_s": "Freeman, Gordon",        
            "comment_s": "Great book!"      
        },
        {
            "type_s": "review",
            "id_l": "4294967454",       
            "reviewer_s": "Delacroix, Marie",       
            "comment_s": "Too many dwarves!"        
        }
    }

If i want to get all books having a review by "Freeman", I would do like this:

&fq={!parent which='type_s:book'}type_s:review AND reviewer_s:Freeman

This would give me two books as result.

But how would I do if I wanted to get all books NOT having a review by "Freeman"?

I've tried like this

&fq={!parent which='type_s:book'}type_s:review AND reviewer_s:(NOT Freeman)

this gives me 0 results

and this

&fq={!parent which='type_s:book'}type_s:review AND NOT reviewer_s:Freeman)

this gives me all parent documents.

Somewhat more promising is the following, which gives me some results (in my real use case)

&fq={!parent which='type_s:book'}type_s:review AND -reviewer_s:["" TO *]

Note that I tried the queries also with the searched term in single quotes.

It would be achievable if solr would have functionality like include_in_parent in elasticsearch . However if you index your data slightly in different way you will be able to achieve what you want. You need to index reviewers as multivalued fields in parent documents (actually elasticsearch does this exast thing behind the scenes when you use include_in_parent ):

[{                                                                                                                                                                                                        
    "type_s": "book",                                                                                                                                                                                     
    "id": 4294967298,                                                                                                                                                                                     
    "title_s": "The Little Mermaid",                                                                                                                                                                      
    "reviewers_ms": ["Freeman, Gordon", "Denton, J.C."],                                                                                                                                                  
    ...                                                                                                                                                                                                   
}, {                                                                                                                                                                                                      
    "type_s": "book",                                                                                                                                                                                     
    "id": 4294967299,                                                                                                                                                                                     
    "title_s": "Lion King",                                                                                                                                                                               
    "reviewers_ms": ["Woods, Susanne", "Denver, Michel"],                                                                                                                                                 
    ...                                                                                                                                                                                                   
}, {                                                                                                                                                                                                      
    "type_s": "book",                                                                                                                                                                                     
    "id": 4294967300,                                                                                                                                                                                     
    "title_s": "7 dwarves",                                                                                                                                                                               
    "reviewers_ms": ["Freeman, Gordon", "Delacroix, Marie"],                                                                                                                                              
    ...                                                                                                                                                                                                   
}]

And then you'll get wanted result if you filter by:

type_s:book AND -reviewers_ms:"Freeman, Gordon"

Update

I've found a way to solve a problem without special indexing. This filter worked for me:

type_s:book AND -{!parent which='type_s:book' v='reviewer_s:"Freeman, Gordon"'}

this syntax should also fix your problem that you've mentioned in comment

However, what if I have another field, say "reviewer_type" in the nested documents, and I'd like to filter in a combined way?

type_s:book AND -{!parent which='type_s:book' v='reviewer_s:"Freeman, Gordon" AND type_s:"review"'}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM