将must和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相结合的组合:

获取包含(foo AND bar in name) OR (foo AND bar in info)的所有文档。在此之后,根据条件state=1和具有图像的boost文档筛选结果。

我一直试图使用bool查询与must,但我未能获得布尔ORmust子句。以下是我所拥有的:

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
}
}
}
]
}
}
}

如你所见,缺少了infomust条件。

**更新**

我已经更新了我的elasticsearch查询,并摆脱了该函数得分。我的基本问题仍然存在。

254457 次浏览

我终于设法创建了一个查询,它确实是我想要的:

一个过滤的嵌套布尔查询。 我不确定为什么这没有被记录下来。也许有人能告诉我?< / p >

下面是查询:

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
}
}
}
}
}

在pseudo-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_not

例子:

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

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

你也可以做更复杂的OR版本,例如,如果你想匹配5个中的至少3个,你可以在“should”下面指定5个选项。并设置一个“最小应该”;3。

感谢格伦·汤普森和塞巴斯蒂安·阿隆索,他们找到了我以前筑巢不太合适的地方。

也感谢Fatmajk指出"term"变成“match”;ElasticSearch Version 6。

$filterQuery = $this->queryFactory->create(QueryInterface::TYPE_BOOL, ['must' => $queries,'should'=>$queriesGeo]);

must中,你需要添加你想要使用AND的查询条件数组,在should中,你需要添加你想要使用OR的查询条件。

你可以检查这个:https://github.com/Smile-SA/elasticsuite/issues/972

这就是如何在一个外部bool查询中嵌套多个bool查询 这使用Kibana,

  • 保龄球表示我们正在使用布尔值
  • 必须代表
  • 应该代表
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"”中有更多类型就像,

  1. 过滤器
  2. must_not

如果你正在使用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)"
}
}
}

也就是说,你可能想要使用布尔查询,就像你已经发布的那个,或者甚至是两者的组合。