思维导图
term 是什么
term
是 ES 中非常重要的概念,用于表示文档中一个单独的词。
在上文我们提到,ES 在全文搜索前(match),会先将输入分词,分解为一个个 term(词)。这里我们再复习下。
例如
GET /mytest/_search
{
"query": {
"match": {
"name": "are you ok"
}
}
}
输入 are you ok
会被分词为以下 3 个term。
are、you、ok。
当使用 term 查询时,ES 会把输入当成一个词。term 具备以下特点
精准匹配
不分词
大小写敏感
下面,开始介绍如何使用 term。
term
简单 demo
写入测试数据
PUT /mytest/_doc/1
{
"name": "Are you OK?"
}
PUT /mytest/_doc/2
{
"name": "I am Very Nice"
}
PUT /mytest/_doc/3
{
"name": "I lIke Es"
}
GET /mytest/_search
{
"query": {
"term": {
"name": {
"value": "ok"
}
}
}
}
搜索时,将 ok
当成一个词,到 name 中查询。 因为 name 的数据结构类型为 text
(下一节会讲解 ES 的数据结构)。因此,name 存储时会被分词。
例如,文档1 的 name
, 会被分为3个词 are
, you
, ok
。记得上一篇我们说过的吧,不区分大小写!!!
因为只有文档1 有 ok 这个词,所以,只有文档1 符合查询条件。
大小写敏感
我们再来看另外一个查询
GET /mytest/_search
{
"query": {
"term": {
"name": {
"value": "oK"
}
}
}
}
注意,K
是大写的。 将 oK
当成一个词(大小写敏感),到 name 中查询。文档 1~3 都没有符合的。
不分词
再来看另一个查询
GET /mytest/_search
{
"query": {
"term": {
"name": {
"value": "Are you"
}
}
}
}
将 Are you
当成一个词,到 name 中查询。文档 1~3 都没有符合的。
如果我们将 term 查询换成上章讲解的 match 查询,你会发现,以上查询都有匹配记录。因为 match 查询会 将输入分词、且不区分大小写
。
case_insensitive-参数控制大小写敏感
从 ES 7.10.0
开始, ES 支持参数控制大小写敏感
GET /mytest/_search
{
"query": {
"term": {
"name": {
"value": "oK",
"case_insensitive": true
}
}
}
}
boost-调整权重
类似的,term 查询的字段,也可以设置算分权重
GET /mytest/_search
{
"query": {
"term": {
"name": {
"value": "ok",
"boost": 2
}
}
}
}
terms
可以查多个 term,很好理解,不过多解释
GET /mytest/_search
{
"query": {
"terms": {
"name": [
"are",
"like"
]
}
}
}
exists
存在该字段的文档
GET /mytest/_search
{
"query": {
"exists": {
"field": "age"
}
}
}
在业务开发中,我们很经常会查询某个字段 不存在 于该文档中。这个时候,可以用以下查询
GET /mytest/_search
{
"query": {
"bool": {
"must_not": [
{
"exists": {
"field": "age"
}
}
]
}
}
}
PS:bool query
会在下下一章节中介绍。
IDs
对 _id
进行查询,提供了专门的 API
GET /mytest/_search
{
"query": {
"ids": {
"values": ["1","2","3"]
}
}
}
上述写法等同于以下写法
GET /mytest/_search
{
"query": {
"terms": {
"_id": [
"1",
"2",
"3"
]
}
}
}
term、match 区别
上文我们介绍完了 match、term 查询。这边稍微做下总结:
- term 完整匹配整个输入,正常 term 的查询性能会优于 match。
- match 对输入进行分词,然后匹配每个分词(需要注意的是,当在 keyword 类型下使用 match 时,他的表现和 term 一样)。