Elasticsearch:以更简单的方式编写具有逻辑条件的 Elasticsearch 查询 - query_string

·  阅读 2188

当涉及到诸如 NOT、AND 和 OR 之类的布尔运算时,我们通常使用带有 must、should、must_not 子句的布尔查询。 是的,bool 查询非常强大,可用于执行所有类型的高级搜索。 但是,对于具有基本 NOT、AND 和 OR 条件的简单搜索,使用 bool 查询有点矫枉过正,因为你需要编写大量样板代码。 这是 query_string 查询适合的地方,因为它具有更简单的语法。针对 query_string,在我的另外一篇文章 “Elasticsearch: query_string 查询” 有详细介绍。

准备数据

如果你还没有准备好你的数据,请阅读我之前的文章 “Elasticsearch:通过例子快速入门”。我们通过文章里介绍的方法把索引  laptops-demo 建立起来。这里不再累述了。

NOT operation

让我们找出 brand 不是 HP 的笔记本电脑。 配合 bool 查询,代码如下:



1.  GET laptops-demo/_search
2.  {
3.    "query": {
4.      "bool": {
5.        "must_not": [
6.          {
7.            "match": {
8.              "brand": "hp"
9.            }
10.          }
11.        ]
12.      }
13.    }
14.  }


复制代码

如你所见,我们需要使用 bool/must_not 样板代码(以及大量括号)来编写具有简单 NOT 条件的查询。 使用 query_string 查询,语法更简单、更灵活。 以下所有将起作用并给出相同的结果:

`

1.  GET laptops-demo/_search
2.  {
3.    "query": {
4.      "query_string": {
5.        "default_field": "brand",
6.        "query": "NOT hp"
7.      }
8.    }
9.  }

11.  GET laptops-demo/_search
12.  {
13.    "query": {
14.      "query_string": {
15.        "default_field": "brand",
16.        "query": "!hp"
17.      }
18.    }
19.  }

21.  GET laptops-demo/_search
22.  {
23.    "query": {
24.      "query_string": {
25.        "query": "brand:(NOT hp)"
26.      }
27.    }
28.  }

30.  GET laptops-demo/_search
31.  {
32.    "query": {
33.      "query_string": {
34.        "query": "brand:(!hp)"
35.      }
36.    }
37.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
复制代码
  • 要搜索的字段可以使用 default_fieldfields 参数指定,或直接在查询中指定。 当在查询中指定时,它后面应该跟一个冒号,布尔条件应该放在括号中。
  • 使用 query_string 以更简单的方式指定布尔条件。 例如,你可以使用 NOT 或感叹号 ! 指定 NOT 条件。 当存在 AND 或 OR 条件时,它会更加突出。

AND operation

让我们找到 brand 为 HP 且名称中包含 EliteBook 的笔记本电脑:

`

1.  GET laptops-demo/_search
2.  {
3.    "query": {
4.      "bool": {
5.        "must": [
6.          {
7.            "match": {
8.              "brand": "hp"
9.            }
10.          },
11.          {
12.            "match": {
13.              "name": "elitebook"
14.            }
15.          }
16.        ]
17.      }
18.    }
19.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
复制代码

嗯,这里有点失控了,因为你需要非常小心嵌套查询,不要错过任何方括号或大括号。 同样,使用 query_string 更简单:



1.  GET laptops-demo/_search
2.  {
3.    "query": {
4.      "query_string": {
5.        "query": "brand: hp AND name: elitebook"
6.      }
7.    }
8.  }


复制代码

哇,这简单多了,不是吗? 没有样板代码和带有令人眼花缭乱的括号的疯狂嵌套。

请注意,当使用 query_string 时,如果查询具有逻辑条件,则需要将查询放在括号中。 例如,我们只列出 brand 为 HP 但不是 EliteBook 的笔记本电脑:



1.  GET laptops-demo/_search
2.  {
3.    "query": {
4.      "query_string": {
5.        "query": "brand: hp AND name: (NOT elitebook)"
6.      }
7.    }
8.  }


复制代码

它非常简单易读。 如果使用 bool 查询,则需要同时使用 must 和 must_not 子句,这会变得更加复杂:

`

1.  GET laptops-demo/_search
2.  {
3.    "query": {
4.      "bool": {
5.        "must": [
6.          {
7.            "match": {
8.              "brand": "hp"
9.            }
10.          }
11.        ],
12.        "must_not": [
13.          {
14.            "match": {
15.              "name": "elitebook"
16.            }
17.          }
18.        ]
19.      }
20.    }
21.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
复制代码

OR operation

为了完整起见,让我们检查 OR 条件并找到 brand 为 Dell 或 name 中有 EliteBook 的笔记本电脑(仅供演示 😃)。 对于 bool 查询,你需要使用 should 子句:

`

1.  GET laptops-demo/_search
2.  {
3.    "query": {
4.      "bool": {
5.        "should": [
6.          {
7.            "match": {
8.              "brand": "dell"
9.            }
10.          },
11.          {
12.            "match": {
13.              "name": "elitebook"
14.            }
15.          }
16.        ]
17.      }
18.    }
19.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
复制代码

使用 query_string 查询,就简单多了:



1.  GET laptops-demo/_search
2.  {
3.    "query": {
4.      "query_string": {
5.        "query": "brand: dell OR name: elitebook"
6.      }
7.    }
8.  }


复制代码

我认为你已经明白使用 query_string 比使用 bool 查询要简单得多。 我们刚刚介绍了 query_string 查询的本质,还有很多其他有用的功能可以在官方文档中找到。 但是,只有在需要使用更高级的功能时才需要学习它们。

尽管 query_string 对于简单查询非常方便,但如官方文档所述,它不方便也不推荐用于 nested 文档。 对于 nested 文档的查询,最好使用这篇文章中更详细演示的 nested 查询。

分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改