1.概述

转载:Elasticsearch能检索出来,但不能正确高亮怎么办?

官网参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-ngram-tokenizer.html

1、问题引出

微信群里的线上实战问题:

诸位大哥,es中:

keyword类型的字段进行高亮查询,值为 123asd456,查询 sd4,高亮结果是 em 123asd456 em

有没有办法只对我查询的sd4高亮?

明明查询id的一部分,却高亮结果是整个id串,怎么办?

死磕Elasticsearch技术微信群

2、一个Demo描述清楚问题

注:本文示例DSL在7.2版本运行ok,6.X之前早期版本可能需要微调。

PUT findex
{"mappings": {"properties": {"aname":{"type":"text"},"acode":{"type":"keyword"}}}
}POST findex/_bulk
{"index":{"_id":1}}
{"acode":"160213.OF","aname":"X泰纳斯达克100"}
{"index":{"_id":2}}
{"acode":"160218.OF","aname":"X泰国证房地产"}POST findex/_search
{"highlight": {"fields": {"acode": {}}},"query": {"bool": {"should": [{"wildcard": {"acode": "*1602*"}}]}}
}

高亮检索结果,

  "highlight" : {"acode" : ["<em>160213.OF</em>"]}

也就是说整个串都被高亮了,没有达到预期。

实际需求:搜索1602,相关数据:160213.O、160218.OF都能召回,且仅高亮搜索字段1602。

3、问题拆解

  • 检索选型wildcard是为了解决子串能匹配的问题,wildcard的实现类似mysql的“like”模糊匹配。

  • 传统的text标准分词器,包括中文分词器ik、英文分词器english、standard等都不能解决上述子串匹配问题。

而实际业务需求:

一方面:要求输入子串召回全串;

另一方面:要求高亮检索的子串。

只能更换一种分词Ngram来实现了!

4、什么是Ngram?

4.1 Ngram定义

Ngram是一种基于统计语言模型的算法。

Ngram基本思想:是将文本里面的内容按照字节进行大小为N的滑动窗口操作,形成了长度是N的字节片段序列。每一个字节片段称为gram,对所有gram的出现频度进行统计,并且按照事先设定好的阈值进行过滤,形成关键gram列表,也就是这个文本的向量特征空间,列表中的每一种gram就是一个特征向量维度。

该模型基于这样一种假设,第N个词的出现只与前面N-1个词相关,而与其它任何词都不相关,整句的概率就是各个词出现概率的乘积。

这些概率可以通过直接从语料中统计N个词同时出现的次数得到。常用的是二元的Bi-Gram(二元语法)和三元的Tri-Gram(三元语法)。

4.2 Ngram举例

中文句子:“你今天吃饭了吗”,它的Bi-Gram(二元语法)分词结果为:

你今
今天
天吃
吃饭
饭了
了吗

4.3 Ngram 应用场景

  • 场景1:文本压缩、检查拼写错误、加速字符串查找、文献语种识别。

  • 场景2:自然语言处理自动化领域得到新的应用,如自动分类、自动索引、超链的自动生成、文献检索、无分隔符语言文本的切分等。

  • 场景3:自然语言的自动分类功能。对应到Elasticsearch检索,应用场景就更加明确:无分隔符语言文本的切分分词,提高检索效率(相比:wildcard 查询和正则查询)。

5、实践一把

PUT findex_ext
{"settings": {"index.max_ngram_diff": 10,"analysis": {"analyzer": {"my_analyzer": {"tokenizer": "my_tokenizer"}},"tokenizer": {"my_tokenizer": {"type": "ngram","min_gram": 4,"max_gram": 10,"token_chars": ["letter","digit"]}}}},"mappings": {"properties": {"aname": {"type": "text"},"acode": {"type": "text","analyzer": "my_analyzer","fields": {"keyword": {"type": "keyword"}}}}}
}POST findex_ext/_bulk
{"index":{"_id":1}}
{"acode":"160213.OF","aname":"X泰纳斯达克100"}
{"index":{"_id":2}}
{"acode":"160218.OF","aname":"X泰国证房地产"}# 查看分词结果
POST findex_ext/_analyze
{"analyzer": "my_analyzer","text":"160213.OF"
}POST findex_ext/_search
{"highlight": {"fields": {"acode": {}}},"query": {"bool": {"should": [{"match_phrase": {"acode": {"query": "1602"}}}]}}
}

注意:三个核心参数

  • min_gram:最小字符长度(切分),默认为1

  • max_gram:最大字符长度(切分),默认为2

  • token_chars:生成的分词结果中包含的字符类型,默认是全部类型。如上的示例中代表:保留数字、字母。若上述示例中,只指定 “letter”,则数字就会被过滤掉,分词结果只剩下串中的字符如:“OF”。

返回结果截取片段如下:

    "highlight" : {"acode" : ["<em>1602</em>13.OF"]}

已经能满足检索和高亮的双重需求。

5、选型注意
Ngram的本质:用空间换时间。其能匹配的前提是写入的时候已经按照:min_gram、max_gram切词。

数据量非常少且不要求子串高亮,可以考虑keyword。

数据量大且要求子串高亮,推荐使用:Ngram分词结合match或者match_phrase检索实现。

数据量大,切记不要使用wildcard前缀匹配!

原因:带有通配符的pattern构造出来的DFA(Deterministic Finite Automaton)可能会很复杂,开销很大!甚至可能导致线上环境宕机。

Wood大叔也 多次强调:wildcard query应杜绝使用通配符打头,实在不得已要这么做,就一定需要限制用户输入的字符串长度。

6、小结

为讨论解决线上问题,引申出Ngram的原理和使用逻辑,并指出了wildcard和Ngram的适用业务场景。希望对实战中的你有所启发和帮助!

你在业务中遇到子串匹配和高亮的情况吗?你是如何分词和检索的?欢迎留言讨论。

参考:

1、https://zhuanlan.zhihu.com/p/32829048

2、http://blog.sciencenet.cn/blog-713101-797384.html

3、https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-ngram-tokenizer.html

4、https://elasticsearch.cn/article/171

【Elasticsearch】Elasticsearch能检索出来,但不能正确高亮怎么办 高亮部分数据 高亮指定字符串 Ngram相关推荐

  1. 用 mongodb + elasticsearch 实现中文检索

    2019独角兽企业重金招聘Python工程师标准>>> 而 elasticsearch 可以很好的支持各种语言的全文检索,但我们暂时又不想切换到 elasticsearch 作为后端 ...

  2. java es scroll,Elasticsearch Scroll分页检索案例分享

    Elasticsearch Scroll分页检索案例分享 1.准备工作 2.定义scroll检索dsl 首先定义一个简单的scroll dsl检索脚本 { ## 这里都是用常量在操作,实际场景中可以参 ...

  3. Elasticsearch 4: 相关性检索和组合查询

    目录 1. 相关性评分 2. 相关度模型 2.1 布尔模型 2.2 向量空间模型 2.3 概率模型 2.4 语言模型 3. TF/IDF 4. BM25 4.1 词频饱和度 4.2 长度归一化 5. ...

  4. 怎样正确运用网络舆情大数据?

    随着互联网的迅速发展,大数据带来的信息爆炸正在影响着我们的工作.生活和思维.互联网的信息泛滥深切地影响着我们每个人的生活.网络信息的不断膨胀也给以往的舆情监测工作提出挑战.网络舆情监测要想适应现在大数 ...

  5. 辅助企业正确决策,华为云大数据BI清晰、直观展现企业发展现状!

    辅助企业正确决策,华为云大数据BI清晰.直观展现企业发展现状! 随着数字化新一代技术的飞速发展,企业对于云原生.平台化.aPaaS能力的要求也不断升级.特别是数据处理方面,传统数据分析平台的低性能.低 ...

  6. 你用过Elasticsearch Percolate 反向检索吗?

    Elasticsearch 最少必要知识实战教程直播回放 题记 percolator query 大家肯定在文档中见过,但实际业务中则较少用到. 本文探究一下percolator query的使用方法 ...

  7. es统计有多少个分组_ES 24 - 如何通过Elasticsearch进行聚合检索 (分组统计)

    1 普通聚合分析 1.1 直接聚合统计 (1) 计算每个tag下的文档数量, 请求语法: GET book_shop/it_book/_search { "size": 0, // ...

  8. elasticsearch—索引与检索(一)

    1. 索引介绍 You know, for search (and analysis) 一个 Elasticsearch 集群可以 包含多个 索引(index),相应的每个索引可以包含多个 类型(ty ...

  9. Elasticsearch学习1 入门进阶 Linux系统下操作安装Elasticsearch Kibana 初步检索 SearchAPI Query DSL ki分词库 自定义词库

    文章目录 一.全文检索-Elasticsearch 1.Elasticsearch简介 2.全文搜索引擎 二.docker安装 1.elasticsearch启动 2.kibana启动 三.[入门]初 ...

最新文章

  1. SDE要素类导出为shp格式文件
  2. 刚刚做了个chrome浏览器 博客园转载插件,欢迎试用,多提意见!
  3. Java 洛谷 P1035 级数求和
  4. linux压缩和打包的区别,Linux中的压缩和打包
  5. xp下添加linux启动项,grub.cfg--XP+ Ubuntu10.04双系统安装后无XP启动项
  6. win7 oracle启动监听,win7系统oracle监听服务无法打开的解决方法
  7. inline-block清除空隙2
  8. 台湾印象之五:宝岛万象
  9. Django学习笔记《二》图书管理系统
  10. Linux下配置OpenLDAP服务记录
  11. 阿里云荣获可信云容器安全能力先进级认证, ACK/ACR为企业级安全护航
  12. mysql 1031错误_为什么我的mysql语句一直报错,找不到错误,望各位大佬指点一番...
  13. 每日两道前端面试题20190226
  14. nginx反向代理docker registry报”blob upload unknown解决办法
  15. java 气象数据_中国天气预报数据API收集
  16. SIM800L模块发送短信
  17. adobe 不适应 Max to分屏软件的修改
  18. 我理解的二极管工作原理
  19. mac电脑怎么连接蓝牙鼠标?
  20. [高数][高昆轮][高等数学上][第一章-函数与极限]03.函数的极限

热门文章

  1. 北京严厉打击违规发布网络房源信息行为 18家机构被查处
  2. 1499元被标149元,苹果官网产品出现Bug价后续:白高兴了!
  3. 王国权辞任中国电信股份有限公司执行副总裁
  4. 薅羊毛新思路!腾讯游戏:成年人借未成年人名义申诉退款频发
  5. 金山云和金山办公均成功上市 雷军揭秘背后原因
  6. 5G芯片市场“四强争霸” 未来市场格局谁更胜一筹?
  7. 跨过山和大海的地铁外放党们有人管了,明年开始!网友:没收手机么?
  8. 会玩!今年天猫双11可以买房了 还是特价 网友:满300减40吗?
  9. 扎心!8.5亿网民 超七成月收入5000元以下,网友:这数据很真实
  10. 小米手环4 NFC版将全渠道开售:垃圾分类超智能