我目前正在尝试将一个基于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 AND bar in name) OR (foo AND bar in info)
的文档。之后,根据条件state=1
过滤结果,并提升具有图像的文档。
我一直试图在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
条件。
**更新**
我已经更新了我的弹性搜索查询,并去掉了那个函数得分。我的基本问题仍然存在。
- OR拼写为应
- AND拼写为必须
- NOR拼写为must_not
示例:
您要查看所有项目(圆形AND(红色或蓝色)):
{
"query": {
"bool": {
"must": [
{
"term": {"shape": "round"}
},
{
"bool": {
"should": [
{"term": {"color": "red"}},
{"term": {"color": "blue"}}
]
}
}
]
}
}
}
你也可以做更复杂的OR版本,例如,如果你想匹配5个选项中的至少3个,你可以在"下指定5个选项;应该";并设置一个";最小_应该"共3个。
感谢Glen Thompson和Sebastianoso找到了我以前不太适合筑巢的地方。
还感谢Fatmajk指出;术语";变成";匹配";在ElasticSearch版本6中。
我终于创建了一个查询,它正是我想要的:
已筛选的嵌套布尔查询。我不知道为什么没有记录下来。也许有人能告诉我?
以下是查询:
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语句必须为true。
这句话意味着,只要结果集中有一个文档包含has_image:1,它就会增加100倍。这将更改结果顺序。
"should": [
{
"match": {
"has_image": {
"query": 1,
"boost": 100
}
}
}
]
玩得开心的家伙:)
这就是如何在一个外部布尔查询中嵌套多个布尔查询使用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";比如
- 过滤器
- 必须否
我最近也不得不解决这个问题,经过大量的尝试和错误,我想出了这个(在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
。
希望这能帮助到别人!
如果您使用Solr的默认或Lucene查询解析器,那么您几乎总是可以将其放入查询字符串查询中:
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)"
}
}
}
也就是说,您可能想要使用布尔查询,就像您已经发布的查询一样,或者甚至是两者的组合。
$filterQuery = $this->queryFactory->create(QueryInterface::TYPE_BOOL, ['must' => $queries,'should'=>$queriesGeo]);
在must
中,您需要添加要使用AND
的查询条件数组,在should
中,您还需要添加要与OR
一起使用的查询条件。
您可以检查:https://github.com/Smile-SA/elasticsuite/issues/972