Perhaps something like this?
{
"query":{
"bool":{
"must":[
{
"term":{
"author":"one"
}
},
{
"nested":{
"path":"books",
"query":{
"term":{
"books.title":"two"
}
}
}
}
]
}
}
}
That query basically says that a document Must have author: one
and books.title: two
. You can reconfigure that query easily. For example, if you just want to search for authors, remove the nested part. If you want a different book, change the nested, etc etc.
This assumes you are using the actual Nested documents, and not inner objects. For inner objects you can just use fully qualified paths without the special nested query.
Edit1: You could perhaps accomplish this with clever boosting at index time, although it will only be an approximate solution. If "author" is boosted heavily, it will sort higher than matches to just the title, even if the title matches both parts of the query. You could then use a min_score cutoff to prevent those from displaying.
Its only a loose approximation, since some may creep through. It may also do strange things to the general sorting between "correct" matches.
Edit2: Updated using query_string to expose a "single input" option:
{
"query":{
"query_string" : {
"query" : "+author:one +books.title:two"
}
}
}
That's assuming you are using default "inner objects". If you have real Nested types, the query_string becomes much, much more complex:
{
"query":{
"query_string" : {
"query" : "+author:one +BlockJoinQuery (filtered(books.title:two)->cache(_type:__books))"
}
}
}
Huge Disclaimer I did not test either of these two query_strings, so they may not be exactly correct. But they show that the Lucene syntax is not overly friendly.
Edit3 - This is my best idea:
After thinking about it, your best solution may be indexing a special field that concatenates the author and the book title. Something like this:
{
"author": "one",
"books": [
{
"title": "two",
},
{
"title": "three",
}
],
"author_book": [ "one two", "one three" ]
}
Then at search time, you can do exact Term matches on author_book
:
{
"query" : {
"term" : {
"author_book" : "one two"
}
}
}