elasticsearch布尔查询结合必须与或

我目前正在尝试将基于solr的应用程序迁移到elasticsearch。

我有这个lucene查询

(( name:(+foo +bar) OR info:(+foo +bar) )) AND state:(1) AND (has_image:(0) OR has_image:(1)^100) 

据我所知,这是MUST子句与布尔OR组合的组合:

“获取包含(foo和bar的所有文档)或(foo和bar的信息)的所有文档,然后在条件状态= 1的情况下生成filter,并提升具有图像的文档。

我一直试图使用布尔查询必须,但我没有得到布尔OR或必须从句。 这是我有什么:

 GET /test/object/_search { "from": 0, "size": 20, "sort": { "_score": "desc" }, "query": { "bool": { "must": [ { "match": { "name": "foo" } }, { "match": { "name": "bar" } } ], "must_not": [], "should": [ { "match": { "has_image": { "query": 1, "boost": 100 } } } ] } } } 

正如你所看到的,必须满足“信息”条件。

有没有人有办法解决吗?

非常感谢。

**更新**

我已经更新了我的elasticsearch查询,摆脱了这个function分数。 我的基地问题依然存在。

  • OR拼写“应该”
  • 和拼写“必须”
  • NOR被拼写为“should_not”

例:

你想看到所有的项目(圆形(红色或蓝色)):

 { "query": { "bool": { "must": [ { "term": {"shape": "round"}, "bool": { "should": [ {"term": {"color": "red"}}, {"term": {"color": "blue"}} ] } } ] } } } 

你也可以做更复杂的OR版本,例如,如果你想匹配至less3个5,你可以在“应该”下面指定5个选项,并设置“minimum_should”为3。

我终于设法创build一个查询,正是我想要的:

过滤的嵌套布尔查询。 我不知道为什么这没有logging。 也许这里有人可以告诉我?

这是查询:

 GET /test/object/_search { "from": 0, "size": 20, "sort": { "_score": "desc" }, "query": { "filtered": { "filter": { "bool": { "must": [ { "term": { "state": 1 } } ] } }, "query": { "bool": { "should": [ { "bool": { "must": [ { "match": { "name": "foo" } }, { "match": { "name": "bar" } } ], "should": [ { "match": { "has_image": { "query": 1, "boost": 100 } } } ] } }, { "bool": { "must": [ { "match": { "info": "foo" } }, { "match": { "info": "bar" } } ], "should": [ { "match": { "has_image": { "query": 1, "boost": 100 } } } ] } } ], "minimum_should_match": 1 } } } } } 

在伪SQL中:

 SELECT * FROM /test/object WHERE ((name=foo AND name=bar) OR (info=foo AND info=bar)) AND state=1 

请记住,这取决于你的文档字段分析和映射如何在内部处理name = foo。 这可以从模糊到严格的行为。

“minimum_should_match”:1表示至less有一个should语句必须为真。

这个语句意味着只要结果集中有一个包含has_image:1的文档,就会被因子100提升。这会改变结果顺序。

 "should": [ { "match": { "has_image": { "query": 1, "boost": 100 } } } ] 

玩得开心:)

我最近也不得不解决这个问题,经过大量的反复试验后,我想出了这个(在PHP中,但直接映射到DSL):

 'query' => [ 'bool' => [ 'should' => [ ['prefix' => ['name_first' => $query]], ['prefix' => ['name_last' => $query]], ['prefix' => ['phone' => $query]], ['prefix' => ['email' => $query]], [ 'multi_match' => [ 'query' => $query, 'type' => 'cross_fields', 'operator' => 'and', 'fields' => ['name_first', 'name_last'] ] ] ], 'minimum_should_match' => 1, 'filter' => [ ['term' => ['state' => 'active']], ['term' => ['company_id' => $companyId]] ] ] ] 

在SQL中映射到这样的东西:

 SELECT * from <index> WHERE ( name_first LIKE '<query>%' OR name_last LIKE '<query>%' OR phone LIKE '<query>%' OR email LIKE '<query>%' ) AND state = 'active' AND company_id = <query> 

所有这一切的关键是minimum_should_match设置。 没有这个filter完全覆盖should

希望这可以帮助别人!