match和term等查询语法及原理

通过一个例子说明, 数据如下, 总共有5个数据(对应的字段名是name,类型是text):

hello world
hello Tom world
hello Tom Rob world
hello kilo
world hu
term

精确查询,搜索前不会再对搜索词进行分词,所以我们的搜索词必须是文档分词集合中的一个.

例如当搜索词是"hello world"时, 由于"hello world"并不是一个文档分词(该单词在插入索引时, 会将hello world拆成hello和world两个单词). 所以搜索结果是0.

当搜索词是hello的时候, 结果如下:

GET /test/_search
{
  "query":{
   "term": {
     "name": {
       "value": "hello"
     }
   }
  }
}
# 结果如下
hello world
hello Tom world
hello Tom Rob world
hello kilo

那如果我想精确搜索, 类似于sql中的等于号, 该怎么办?

将name的字段类型设为keyword即可. 因为keyword类型不会对字段进行分词, 而是对整个字段进行索引.

match

会先对搜索词进行分词,分词完毕后再逐个对分词结果进行匹配(匹配的也是分词后的结果),因此相比于term的精确搜索,match是分词匹配搜索.

下面例子查询时, 句子中包含helloworld的都会被搜索出来, 所以这五条数据都能搜索到.

GET /test/_search
{
  "query":{
    "match": {
      "name": "hello world"
    }
  }
}
# 结果
hello world
hello Tom world
hello Tom Rob world
hello kilo
world hu
match_phrase

查询时, hello和world必须相邻, 才能查出, 所以只能得到一条数据

GET /test/_search
{
  "query":{
    "match_phrase": {
      "name": "hello world"
    }
  }
}
# 结果
hello world

match_phrase在查询时, 也可以使用slop参数来控制间隔多少个词条也可以被查出, 注意此处只需要间隔的词条数小于等于slop即可.

GET /test/_search
{
  "query":{
    "match_phrase": {
      "name": {
        "query": "hello world",
        "slop": 1
      }
    }
  }
}
# 结果, slop为1, 即hello world中间间隔的词条数小于等于1就符合查询条件
hello world
hello Tom world
prefix

前缀搜索. 它会对分词后的term进行前缀搜索

  • 它不会分析要搜索字符串,传入的前缀就是想要查找的前缀
  • 默认状态下,前缀查询不做相关度分数计算,它只是将所有匹配的文档返回,然后赋予所有相关分数值为1。它的行为更像是一个过滤器而不是查询。两者实际的区别就是过滤器是可以被缓存的,而前缀查询不行。
  • 只能找到反向索引中存在的术语

原理:

需要遍历所有倒排索引,并比较每个term是否包含所指定的前缀开头.

下面的例子中如果以hell开头的term很多,那么会有严重的性能问题。但是如果term比较小,可以放心使用。

GET /test/_search
{
  "query":{
    "prefix": {
      "name": {
        "value": "hell"
      }
    }
  }
}
# 结果
hello world
hello Tom world
hello Tom Rob world
hello kilo
wildcard

模糊查询

  • 工作原理和prefix相同,只不过它并不是只比较开头,它能支持更为复杂的匹配模式。
  • 它使用标准的 shell 模糊查询:? 匹配任意字符,* 匹配0个或多个字符。
Term:          Doc IDs:
-------------------------
"SW50BE"    |  5
"W1F7HW"    |  3
"W1V3DG"    |  1
"W2F8HW"    |  2
"WC1N1LZ"   |  4
-------------------------

GET /my_index/address/_search
{
    "query": {
        "prefix": {
            "postcode": "W1"
        }
    }
}

参考文档:

https://hao5743.github.io/2019/07/11/2019-07-16/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值