Elasticsearch实现内容精确匹配查询

一、 问题描述

  1. 需要搜索的内容为:【飞科剃须刀】
  2. 实际搜索,需要满足的条件:
    a.检索关键词“飞科”,“剃须”、“刀”,都能搜出这篇文档。
    b.干扰搜索“水果刀”,文档不要被检索出来。
    c.单个字拆分“剃”、“须”太多干扰文档不要被检索出来。
    d.待检索的词“科剃”、“科剃须”不在词典中,但只要在原文中出现,都要检索到。
    e.检索关键词“飞科剃须”,能搜出这篇文档
    f.检索速度要快,不影响性能。
  3. 分词测试:
  • Standard分词器
GET /my_index/_analyze
{
	"text":"飞科剃须刀",
	"analyzer":"standard"
}
分词结果:飞、科、剃、须、刀
  • ik_max_word分词器
GET /my_index/_analyze
{
	"text":"飞科剃须刀",
	"analyzer":"ik_max_word"
}
分词结果:飞、科、剃须刀、剃须、刀
  • ik_smart分词器
GET /my_index/_analyze
{
	"text":"飞科剃须刀",
	"analyzer":"ik_smart"
}
分词结果:飞、科、剃须刀

二、问题分析

  1. 针对要求a,可以采用全文检索(match、match_phrase)。
  • match查询实现精确匹配
GET /my_index/_search
{
  "query":{
	"match":{
	  "qss":{
		"query":"飞科"  //分别尝试“剃须”、“刀”,都能检索到包含“飞科剃须刀”的文档
	  }
	}
  }
}
  • match_phrase查询实现完全匹配
    文档同时满足下面两个条件才会被搜索到:
    (1)分词后所有词项都要出现在该字段中
    (2)字段中的词项顺序要一致
GET my_index/_search
{
  "query": {
    "match_phrase": {
      "qss": "飞科" //分别尝试“剃须”、“刀”,都能检索到包含“飞科剃须刀”的文档
    }
  }
}
  1. 针对要求b,match查询检索范围太大、干扰太多,排除;ik_smart分词器没有“剃须”词项,排除match查询后,与 match_phrase 结合使用,依然检索不到,故排除。
  2. 针对要求c,standard 分词器会出现非常多冗余数据,排除。
  3. 针对要求d,ik_max_word 有些词项不包含,排除。
  4. 针对要求e,match_phrase 查询不到,排除。
  5. 针对要求f,wildcard 模糊查询影响性能,排除。

三、为什么会检索不到?

  1. 分词原因/词典未收录原因。
    在上文问题d中,由于分词器中不包含“科剃”等词项,所以检索不到。
  2. postition位置不一致。
    在上文问题e中,由于分词器分词器对“飞科剃须”和“飞科剃须刀”分词的postition位置不一致,所以检索不到。
飞科剃须飞科剃须刀
tokenpositiontokenposition
00
11
剃须2剃须刀2
剃须3
4

四、解决方案

1. match_phrase_prefix结合slop的方案
GET my_index/_search
{
  "query": {
    "match_phrase_prefix": {
      "qss": {
        “query”:"飞科剃须",
        “slop”:1      //指定相邻词之间允许相隔多远。设置为0,则为完全匹配。
	  }
    }
  }
}

能应对一部分业务。但是分析发现:slop设置不论多大、多小,都可能会引入噪音数据,导致结果不准确。

2. match_phrase结合match should关联匹配。

依然会引入噪音数据。

3. 终极方案:逐个字分词和ik分词结合的方式。
  • mapping设置:
PUT mx_index
 {
   "mappings": {
     "_doc": {
       "properties": {
         "qss": {
           "type": "text",
           "analyzer": "ik_max_word",
           "fields": {
            "standard": {
              "type": "text",
              "analyzer": "standard"
            },
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        }
      }
    }
  }
}
  • 搜索:
GET mx_index/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match_phrase": {
            "qss": "科剃"
          }
        },
        {
          "match_phrase": {
            "qss.standard": "科剃"
          }
        }
      ]
    }
  }
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值