前言

  • 本文对 ES 7.17 适用
  • 需要探讨的问题
["zhang san", "li si"] 写入 ES 索引
match_phrase 查询 san li
会不会串门搜索出文档?
{
    "match_phrase": {
        "name.text": {
            "query": "san li"
        }
    }
}
  • 以下测试均使用 ES 内置的 simple 分词器

试验过程

直接查看分词结果

GET _analyze
{
  "analyzer": "simple", 
  "text": ["zhang san", "li si"],
  "explain": false,
  "attributes" : ["keyword"]
}

可以看到分词结果 position

0 zhang
1 san
2 li
3 si

新建索引并写入数据

  • 创建 my_index 索引
PUT my_index
{
  "mappings": {
    "dynamic": false,
    "properties": {
      "name": {
        "type": "keyword",
        "fields": {
          "text": {
            "type": "text",
            "analyzer": "simple"
          }
        }
      }
    }
  }
}
  • 写入数据
POST my_index/_bulk
{ "index" : { "_id" : "1" } }
{ "name" : ["zhang san", "li si"]}
  • 查看数据
GET my_index/_doc/1
{
  "_index" : "my_index",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 5,
  "_seq_no" : 4,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : [
      "zhang san",
      "li si"
    ]
  }
}

分词 position

  • 查看 name.text 的分词 position
GET my_index/_termvectors/1?fields=name.text

可以看到分词结果 position

  0 zhang
  1 san
102 li
103 si
  • match 语句可以 san li 查询得到结果
GET my_index/_search
{
  "query": {
    "match": {
      "name.text": "san li"
    }
  }
}
  • match_pharse 语句不能 san li 查询得到结果
# 默认 slop 为 0
GET my_index/_search
{
  "query": {
    "match_phrase": {
      "name.text": {
        "query": "san li"
      }
    }
  }
}
  • slop 设为 10 还是不能查询得到结果
GET my_index/_search
{
  "query": {
    "match_phrase": {
      "name.text": {
        "query": "san li",
        "slop": 10
      }
    }
  }
}
  • slop 设为 100 可以查询得到结果
GET my_index/_search
{
  "query": {
    "match_phrase": {
      "name.text": {
        "query": "san li",
        "slop": 100
      }
    }
  }
}

小结

  • position 位置观察
0    0  zhang
1    1  san
2  102  li
3  103  si
  • 可以看到 li2 跳到 102 刚好距离 100
  • ES 通过分词 position 巧妙的将数组元数的分词做了隔离
本文出自 qbit snap

qbit
268 声望279 粉丝