elasticsearch如何使用Ngram实现任意位数手机号搜索
Ngram自定义分词案例
当对keyword类型的字段进行高亮查询时,若值为123asd456,查询sd4,则高亮结果是<em>123asd456<em>。那么,有没有办法只对sd4高亮呢?用一句话来概括问题:明明只想查询ID的一部分,但高亮结果是整个ID串,此时应该怎么办?
实战问题拆解
###定义索引
PUT my_index_0602
{
"mappings": {
"properties": {
"phoneNum": {
"type": "keyword"
}
}
}
}
####批量写入数据
POST my_index_0602/_bulk
{"index":{"_id":1}}
{"phoneNum":"13511112222"}
{"index":{"_id":2}}
{"phoneNum":"13844248474"}
###执行模糊检索和高亮显示
POST my_index_0602/_search
{
"highlight": {
"fields": {
"phoneNum": {}
}
},
"query": {
"bool": {
"should": [
{
"wildcard": {
"phoneNum": "*1111*"
}
}
]
}
}
}高亮检索结果如下。

也就是说,整个字符串都呈现为高亮状态了,没有达到预期。
检索过程中选择使用wildcard是为了解决子串匹配的问题,wildcard的实现逻辑类似于MySQL的like模糊匹配。传统的text标准分词器,包括中文分词器ik、英文分词器english、standard等都不能解决上述子串匹配问题。
而实际业务需求是这样的:一方面要求输入子串能召回全串;另一方面要求检索的子串实现高亮。对此,只能更换一种分词来实现,即Ngram。
Ngram分词器定义
Ngram分词定义
Ngram是一种基于统计语言模型的算法。Ngram基本思想是将文本里面的内容按照字节大小进行滑动窗口操作,形成长度是N的字节片段序列。此时每一个字节片段称为gram。对所有gram的出现频度进行统计,并且按照事先设定好的阈值进行过滤,形成关键gram列表,也就是这个文本的向量特征空间。列表中的每一种gram就是一个特征向量维度。
该模型基于这样一种假设,第N个词的出现只与前面N-1个词相关,而与其他任何词都不相关,整句的概率就是各个词出现概率的乘积。这些概率可以通过直接从语料中统计N个词同时出现的次数得到。常用的是二元的Bi-Gram(二元语法)和三元的Tri-Gram(三元语法)。
Ngram分词示例
以“你今天吃饭了吗“这一中文句子为例,它的Bi-Gram分词结果如下。

Ngram分词应用场景
场景1:文本压缩、检查拼写错误、加速字符串查找、文献语种识别。
场景2:自然语言处理自动化领域得到新的应用。如自动分类、自动索引、超链的自动生成、文献检索、无分隔符语言文本的切分等。
场景3:自然语言的自动分类功能。针对Elasticsearch检索,Ngram针对无分隔符语言文本的分词(比如手机号检索),可提高检索效率(相较于wildcard检索和正则匹配检索来说)
Ngram分词实战
###定义索引
PUT my_index_0603
{
"settings":{
"number_of_shards":1,
"number_of_replicas":0,
"index.max_ngram_diff" : 10,
"analysis":{
"analyzer":{
"phoneNo_analyzer":{
"tokenizer": "phoneNo_analyzer"
}
},
"tokenizer":{
"phoneNo_analyzer":{
"type": "ngram",
"min_gram": 4,
"max_gram": 11,
"token_chars": [
"letter","digit"
]
}
}
}
},
"mappings":{
"dynamic":"strict",
"properties":{
"phoneNo":{
"type":"text",
"analyzer": "phoneNo_analyzer"
}
}
}
}
####批量写入数据
POST my_index_0603/_bulk
{"index":{"_id":1}}
{"phoneNo":"13511112222"}
{"index":{"_id":2}}
{"phoneNo":"13844248474"}
POST my_index_0603/_analyze
{
"analyzer": "phoneNo_analyzer",
"text": "13511112222"
}
POST my_index_0603/_search
{
"highlight": {
"fields": {
"phoneNo": {}
}
},
"query": {
"bool": {
"should": [
{
"match_phrase": {
"phoneNo": "1111"
}
}
]
}
}
}
到此这篇关于elasticsearch如何使用Ngram实现任意位数手机号搜索的文章就介绍到这了,更多相关elasticsearch任意位数手机号搜索内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
superset在linux和windows下的安装和部署详细教程
Superset 是 Airbnb开源的数据探查与可视化平台,是个轻量级的BI工具,开发者可以在其开源代码上根据需要进行二次开发。这篇文章主要介绍了superset在linux和windows下的安装和部署详细教程,需要的朋友可以参考下2020-10-10
解决Visual Studio 2019本地不能运行Azure Functions
本文主要介绍了Visual Studio 2019本地不能运行Azure Functions的解决方方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2021-06-06
Elasticsearch索引的分片分配Recovery使用讲解
这篇文章主要为大家介绍了Elasticsearch索引的分片分配Recovery使用讲解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2022-04-04
如何配置openai的返回Stream数据并转发到h5页面按markdown格式流式输出(最新推荐)
这篇文章主要介绍了如何配置openai的返回Stream数据并转发到h5页面按markdown格式流式输出,本文通过示例代码演示如何使用OpenAI API来实现流式输出并分段加载,需要的朋友可以参考下2023-05-05
C++ Go语言实现将windows和linux文件删除至回收站
这篇文章主要为大家详细介绍了如何分别使用C++ Go语言实现将windows和linux文件删除至回收站,感兴趣的小伙伴可以跟随小编一起学习一下2023-12-12


最新评论