大数据利器Elasticsearch之fuzzy相似查询

这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战
本Elasticsearch相关文章的版本为:7.4.2

fuzzy查询:返回包含和搜索的文本相近的文档,相近的计算使用的是Levenshtein edit distance。

edit distance是从一个词转换为另一个词所需要经过的变化次数,包括以下几种变形:

  1. 修改一个字符:box -> fox
  2. 移除一个字符:foot -> foo
  3. 插入一个字符:term -> terms
  4. 调换临近的两个字符:cat -> act

为了寻找相似的分词,fuzzy会在edit distance范围内创建一系列可能的变体或扩充后的变体, 然后返回包含和这些变体一样的文档。

测试数据:

POST /fuzzy_test/_doc/1
{
  "message": "john will go home"
}
复制代码

查询包含hoem相似的文档:因为hoem和文档1的home相似(只需要em进行调换即可),所以会返回文档1

GET /fuzzy_test/_search
{
  "query": {
    "fuzzy": {
      "message": {
        "value": "hoem"
      }
    }
  }
}
复制代码

返回数据:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.21576157,
    "hits" : [
      {
        "_index" : "fuzzy_test",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.21576157,
        "_source" : {
          "message" : "john will go home"
        }
      }
    ]
  }
}
复制代码

fuzzy查询参数介绍

. fuzziness: 设置edit distance的最大长度。有效值为0, 1, 2 和 “AUTO”。设置为”AUTO”时,当输入的文本的长度为0到2的时候,fuzziness的值为0,即必须一样;当输入的文本的长度为3到5的时候,fuzziness的值为1;当输入的文本的长度大于5的时候,fuzziness的值为2
比如当下面的查询的fuzziness的值为0时,将不会匹配到文档1,当为1时,可以匹配到文档1:

GET /fuzzy_test/_search
{
  "query": {
    "fuzzy": {
      "message": {
        "value": "hoem",
        "fuzziness": 0
      }
    }
  }
}

GET /fuzzy_test/_search
{
  "query": {
    "fuzzy": {
      "message": {
        "value": "hoem",
        "fuzziness": 1
      }
    }
  }
}
复制代码

. prefix_length: 当创建变体时,设置前面多少位字符不被改变。

比如下面的查询,当prefix_length的值设为3时,将不会匹配到文档1;低于3时,将可以匹配到文档1.因为两位长度的ho和文档1的home的前面两位相同,但3位长度的hoe和文档1的home不相同。

GET /fuzzy_test/_search
{
  "query": {
    "fuzzy": {
      "message": {
        "value": "hoem",
        "prefix_length": 3
      }
    }
  }
}
复制代码

返回的数据:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

复制代码

. transpositons: 是否允许相邻的两个字符调换位置。默认是true。

下面的查询当设置transpositons=false时进行对message字段查询hoem是不会匹配到home的。

GET /fuzzy_test/_search
{
  "query": {
    "fuzzy": {
      "message": {
        "value": "hoem",
        "transpositions": false
      }
    }
  }
}
复制代码

返回的结果:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享