elasticsearch bool 查询结合必须与或
elasticsearch bool query combine must with OR
我目前正在尝试将基于 solr 的应用程序迁移到 elasticsearch。
我有这个 lucene 查询
((
name:(+foo +bar)
OR info:(+foo +bar)
)) AND state:(1) AND (has_image:(0) OR has_image:(1)^100)
据我了解,这是 MUST 子句与布尔值 OR 的组合:
"Get all documents containing (foo AND bar in name) OR (foo AND bar in info). After that filter results by condition state=1 and boost documents that have an image."
我一直在尝试将布尔查询与 MUST 一起使用,但未能将布尔值 OR 放入 must 子句中。这是我拥有的:
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
}
}
}
]
}
}
}
如您所见,缺少 "info" 的 MUST 条件。
有人有解决办法吗?
非常感谢。
** 更新 **
我更新了我的 elasticsearch 查询并去掉了那个函数分数。我的基本问题仍然存在。
我终于设法创建了一个完全符合我要求的查询:
过滤嵌套布尔查询。
我不确定为什么没有记录。也许这里有人可以告诉我?
这里是查询:
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 表示,至少有一个 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
。
希望这对某人有所帮助!
- 或拼写为should
- AND 拼写为 must
- NOR拼写为should_not
示例:
您想查看所有符合(圆形 AND(红色或蓝色))的项目:
{
"query": {
"bool": {
"must": [
{
"term": {"shape": "round"}
},
{
"bool": {
"should": [
{"term": {"color": "red"}},
{"term": {"color": "blue"}
]
}
}
]
}
}
}
您还可以做更复杂的 OR 版本,例如,如果您想匹配 5 个中的至少 3 个,您可以在“应该”下指定 5 个选项,并将“minimum_should”设置为 3 .
感谢 Glen Thompson 和 Sebastialonso 找到我之前嵌套不正确的地方。
还要感谢 Fatmajk 指出“term”在 ElasticSearch 6 中变成了“match”。
$filterQuery = $this->queryFactory->create(QueryInterface::TYPE_BOOL, ['must' => $queries,'should'=>$queriesGeo]);
在 must
中,您需要添加要使用的查询条件数组 AND
,在 should
中,您需要添加要使用的查询条件OR
.
这是在一个外部 bool 查询中嵌套多个 bool 查询的方法
这使用 Kibana,
- bool 表示我们正在使用 boolean
- 必须 用于 AND
- 应该用于或
GET my_inedx/my_type/_search
{
"query" : {
"bool": { //bool indicates we are using boolean operator
"must" : [ //must is for **AND**
{
"match" : {
"description" : "some text"
}
},
{
"match" :{
"type" : "some Type"
}
},
{
"bool" : { //here its a nested boolean query
"should" : [ //should is for **OR**
{
"match" : {
//ur query
}
},
{
"match" : {}
}
]
}
}
]
}
}
}
这是在 ES 中嵌套查询的方法
“bool”中还有更多类型,例如,
- 过滤器
- must_not
如果您使用的是 Solr 的默认或 Lucene 查询解析器,您几乎总是可以将其放入 query string 查询中:
POST test/_search
{
"query": {
"query_string": {
"query": "(( name:(+foo +bar) OR info:(+foo +bar) )) AND state:(1) AND (has_image:(0) OR has_image:(1)^100)"
}
}
}
也就是说,您可能想使用 boolean query,就像您已经发布的那样,甚至是两者的组合。
我目前正在尝试将基于 solr 的应用程序迁移到 elasticsearch。
我有这个 lucene 查询
((
name:(+foo +bar)
OR info:(+foo +bar)
)) AND state:(1) AND (has_image:(0) OR has_image:(1)^100)
据我了解,这是 MUST 子句与布尔值 OR 的组合:
"Get all documents containing (foo AND bar in name) OR (foo AND bar in info). After that filter results by condition state=1 and boost documents that have an image."
我一直在尝试将布尔查询与 MUST 一起使用,但未能将布尔值 OR 放入 must 子句中。这是我拥有的:
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
}
}
}
]
}
}
}
如您所见,缺少 "info" 的 MUST 条件。
有人有解决办法吗?
非常感谢。
** 更新 **
我更新了我的 elasticsearch 查询并去掉了那个函数分数。我的基本问题仍然存在。
我终于设法创建了一个完全符合我要求的查询:
过滤嵌套布尔查询。 我不确定为什么没有记录。也许这里有人可以告诉我?
这里是查询:
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 表示,至少有一个 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
。
希望这对某人有所帮助!
- 或拼写为should
- AND 拼写为 must
- NOR拼写为should_not
示例:
您想查看所有符合(圆形 AND(红色或蓝色))的项目:
{
"query": {
"bool": {
"must": [
{
"term": {"shape": "round"}
},
{
"bool": {
"should": [
{"term": {"color": "red"}},
{"term": {"color": "blue"}
]
}
}
]
}
}
}
您还可以做更复杂的 OR 版本,例如,如果您想匹配 5 个中的至少 3 个,您可以在“应该”下指定 5 个选项,并将“minimum_should”设置为 3 .
感谢 Glen Thompson 和 Sebastialonso 找到我之前嵌套不正确的地方。
还要感谢 Fatmajk 指出“term”在 ElasticSearch 6 中变成了“match”。
$filterQuery = $this->queryFactory->create(QueryInterface::TYPE_BOOL, ['must' => $queries,'should'=>$queriesGeo]);
在 must
中,您需要添加要使用的查询条件数组 AND
,在 should
中,您需要添加要使用的查询条件OR
.
这是在一个外部 bool 查询中嵌套多个 bool 查询的方法 这使用 Kibana,
- bool 表示我们正在使用 boolean
- 必须 用于 AND
- 应该用于或
GET my_inedx/my_type/_search
{
"query" : {
"bool": { //bool indicates we are using boolean operator
"must" : [ //must is for **AND**
{
"match" : {
"description" : "some text"
}
},
{
"match" :{
"type" : "some Type"
}
},
{
"bool" : { //here its a nested boolean query
"should" : [ //should is for **OR**
{
"match" : {
//ur query
}
},
{
"match" : {}
}
]
}
}
]
}
}
}
这是在 ES 中嵌套查询的方法
“bool”中还有更多类型,例如,
- 过滤器
- must_not
如果您使用的是 Solr 的默认或 Lucene 查询解析器,您几乎总是可以将其放入 query string 查询中:
POST test/_search
{
"query": {
"query_string": {
"query": "(( name:(+foo +bar) OR info:(+foo +bar) )) AND state:(1) AND (has_image:(0) OR has_image:(1)^100)"
}
}
}
也就是说,您可能想使用 boolean query,就像您已经发布的那样,甚至是两者的组合。