0

I have following document structure:

Movie:
{
    id: int,
    title: string,
    language: string,
    genre: string,
    description: string,
    cast: array[string],
    directors: array[string],
    (...)
}

Now, in the web interface, the user can choose (checkbox) the language, genre, directors etc and type some query to the search box.

Let's say I want to search within all thrillers (genre), that are in French or English (language), directed by James Cameron or George Lucas (directors) and I'm typing to the search box "abc" that I would like to find within title or description.

What I want as a result: - only movies only in French or English - only movies directed by James Cameron or George Lucas - only thrillers - movies that corresponds to "abc"

I'm not sure how to do the OR in the filters, but I have started from something like:

curl -X -XGET 'localhost:9200/movies/_search?pretty' -H 'Content-Type: application/json' -d'
{
   "query" : {
      "constant_score" : { 
         "filter" : {
            "bool" : {
              "should" : [
                 { "term" : {"language" : "french"}}, 
                 { "term" : {"language" : "english"}},
                 { "term" : {"directors" : "James Cameron"}},
                 { "term" : {"directors" : "George Lucas"}}
              ],
              "filter" : [
                 { "term" : {"genre" : "thriller"}}
              ]
           }
         }
      }
   }
}
'

Could you please give me some hints?

1 Answer 1

1

As I understand, you need a query like this: (language is A or B) and (directors is C or D) and (genre is E) and (title or description is F). In this case you need the following query:

{
    "query": {
        "bool": {
            "filter": [
                {
                    "terms": {
                        "language": [
                            "french",
                            "english"
                        ]
                    }
                },
                {
                    "bool": {
                        "should": [
                            {
                                "match": {
                                    "directors": "James Cameron"
                                }
                            },
                            {
                                "match": {
                                    "directors": "George Lucas"
                                }
                            }
                        ]
                    }
                },
                {
                    "term": {
                        "genre": "thriller"
                    }
                },
                {
                    "multi_match": {
                        "query": "abc",
                        "fields": [
                            "title",
                            "description"
                        ]
                    }
                }
            ]
        }
    }
}

filter query will work as AND condition but will get you the same score for all matched documents. If you need to vary score depending on subqueries match, you'd better to use must instead of filter. terms query will match if specified field contains at least one term. multi_match query will match if at least one field contains specified query

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks a lot! The only problem I have is filtering on "directors" - it doesn't work (never returns any result). Should the filter differ for fields that are arrays?
If you use default analyzer, try match query instead of term. It will generate the terms first and will use them for search
Updated my answer with match queries
With "match" it works like a charm. Thank you! Btw, I have realized if I have more than 3 filters in the query, than the query to ES stucks (no response / no logs in the ES). Limitating the number of filters to 3 works... have you ever had this problem?
No, it should work fine. You can post the details as a separate question

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.