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
。
希望这可以帮助别人!