0

I have a question similar to this: Solr - Search parent having multiple child documents

Lets use that same example:

{
    "id": "1",
    "bookName_s": "Core Concepts",
    "bookDescription_s": "This is the description",
    "isbn_s": "ABCD:123",
    "type_s":"book"    
    "reviews": [
      {
        "id": "2",
        "Name_s": "review1",
        "detail_s": "sample review",
        "type":"review"
      }
    ],
    "students": [
      {
        "id": "3",
        "Name_s": "student1",
        "type":"student",
        "student_s": "test student"
      }
    ]
}

Given this structure, the question was how to retrieve all parents (books) that have a review of 'review1' and a student with name 'student1'.

The solution given is:

{!parent which="type:book"}(type:review AND Name_s:review1) OR (type:student AND Name_s:student1)

This however, would also return other books that have a review of 'review1', but not having the 'student1' as student (and vice versa). I would like to retrieve all books that have both the review and the student matching. Only if both match I want the book to be returned. At first you might think replacing OR for AND would do the trick:

{!parent which="type:book"}(type:review AND Name_s:review1) AND (type:student AND Name_s:student1)

But this doesn't return any results. Simply because it now looks for documents with type 'review' AND type 'student' AND Name_s 'review1' AND Name_s 'student1'. These are single-value fields that won't hold both values ever. How can we accomplish what I'm looking for?

Frank
  • 530
  • 5
  • 15
  • 1
    How about using two `fq` statements? `{!parent which="type:book"}(type:review AND Name_s:review1)` and `{!parent which="type:book"}(type:student AND Name_s:student1)` - I've never done much with child documents, but as multiple `fq` gives you the intersection between sets of matching documents, it could work – MatsLindh Oct 13 '22 at 12:42
  • 1
    Thanks, but that does seem to still give me 0 results. However, I got to another solution that comes close to yours. I'm moving the second filter to fq using a join query parser. So you would get: `q={!parent which="type:book"}(type:review AND Name_s:review1)` plus `{!join from=_root_ to=_root_}(type:student AND Name_s:student1)`. That seems to give the right result, but I'm just running some more tests to be sure. – Frank Oct 13 '22 at 12:52

1 Answers1

1

I found a (the?) solution. You can use either multiple fq (fieldquery) parameters or a q (query) and fq parameter to send the following:

q={!parent which="type:book"}(type:review AND Name_s:review1)
fq={!join from=_root_ to=_root_}(type:student AND Name_s:student1)

In this example I defined a _root_ field (which is automatically filled with the parent (book) ID by SOLR). The second statement uses this principle in a Join Query Parser which is similar to a subquery in a relational database. It searches for student1 student and uses its result to filter the result of the main query on ID by joining them together on the root field.

Frank
  • 530
  • 5
  • 15