Elasticsearch:使用过滤器构建bool查询

时间:2017-06-26 08:21:56

标签: search elasticsearch

我有以下文档结构:

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

现在,在网络界面中,用户可以选择(复选框)语言,流派,导演等,并在搜索框中输入一些查询。

假设我想在所有惊悚片(流派)中搜索,这些是法语或英语(语言),由James Cameron或George Lucas(导演)执导,我正在搜索“abc”的搜索框中想在标题或描述中找到。

我想要的结果如何: - 仅限法语或英语的电影 - 只有詹姆斯卡梅隆或乔治卢卡斯执导的电影 - 只有惊悚片 - 对应于“abc”的电影

我不确定如何在过滤器中执行OR,但我从以下内容开始:

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"}}
              ]
           }
         }
      }
   }
}
'
你可以给我一些提示吗?

1 个答案:

答案 0 :(得分:1)

据我了解,您需要这样的查询:(language is A or B) and (directors is C or D) and (genre is E) and (title or description is F)。在这种情况下,您需要以下查询:

{
    "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查询将作为AND条件运行,但会为所有匹配的文档获得相同的分数。如果您需要根据子查询匹配来改变分数,则最好使用must而不是filter。如果指定字段包含至少一个术语,terms查询将匹配。如果至少一个字段包含指定的查询

multi_match查询将匹配