开发者社区> 铭毅天下> 正文

干货 | Elasticsearch 词频统计的四种方案

简介: 1、词频相关实战问题 最近词频统计问题被问到的非常多,词频统计问题清单如下:
+关注继续查看

Q1:Elasticsearch可以根据检索词在doc中的词频进行检索排序嘛?


Q2:求教 ES 可以查询某个索引中某个text类型字段的词频数量最大值和词所在文档数最大值么?例:索引中有两个文档 doc1:{"text":""}  分词结果有两个北京,一个南京 doc2:{"text":""} 分词结果有一个北京想要一下结果:北京:词频3,文档量2 南京:词频1,文档量1


Q3:对某些文章的词频统计除了用fielddata之外还有没有效率比较高的解决办法呢?目前统计有时候会遇到十万级的文章数直接在通过聚合效率上不是特别理想。


如上三个问题都可以归结为:Elasticsearch 文档词频统计问题。该问题在检索、统计领域应用的非常多。


那么 Elasticsearch 如何实现词频统计呢?有必要梳理一下。


2、词频统计探讨

之前的文章《Elasticsearch词频统计实现与原理解读》,解决的是:Q3 提及的某索引中特定关键词统计的问题。


解决方案是:text 字段开启 fielddata,咱们在《长津湖影评可视化


那么,对于给定文档的词频统计呢?


原来开启 fielddata 的方案就可以实现,举例如下:


DELETE message_index

PUT message_index

{

 "mappings": {

   "properties": {

     "message": {

       "analyzer": "ik_smart",

       "type": "text",

       "fielddata": "true"

     }

   }

 }

}

POST message_index/_bulk

{"index":{"_id":1}}

{"message":"沉溺于「轻易获得高成就感」的事情:沉溺于有意无意地寻求用很小付出获得很大「huibao」的偏方,哪怕huibao是虚拟的"}

{"index":{"_id":2}}

{"message":"过度追求“短期huibao”可以先思考这样一个问题:为什么玩王者荣耀沉溺我们总是停不下来huibao"}

{"index":{"_id":3}}

{"message":"过度追求的努力无法带来超额的huibao,就因此放弃了努力。这点在聪明人身上尤其明显。以前念本科的时候身在沉溺"}

POST message_index/_search

{

 "size": 0,

 "query": {

   "term": {

     "_id": 1

   }

 },

 "aggs": {

   "messages": {

     "terms": {

       "size": 10,

       "field": "message"

     }

   }

 }

}

无非在聚合的时候,加上query 语句指定了特定 id 进行检索。


这种方法的缺点在于:正如 Q3 所说,聚合效率低。


看过上次直播的同学,可能会闪现一种想法,写入前打 tag 的方式能解决吗?


可以解决,但有个前提。先画个图解释一下:

image.png

这个打 tag 的字段非全量,而是特定的指定脚本处理的部分。下一小节详细实现一把。


其实,除了开启 fielddata 和 打 tag 之外,在 Elasticsearch 中有 termvectors 接口也能实现文档词频统计。下一小节一并实现。


3、词频统计实现

3.1 text 开启 fielddata 后聚合方案

第 2 部分已有实现说明,不再赘述。


3.2 写入前打 tag,写入后聚合统计方案

还是用第 2 部分的数据,说明如下:


PUT _ingest/pipeline/add_tags_pipeline

{

 "processors": [

   {

     "append": {

       "field": "tags",

       "value": []

     }

   },

   {

     "script": {

       "description": "add tags",

       "lang": "painless",

       "source": """

       if(ctx.message.contains('成就')){

             ctx.tags.add('成就')

          }

           if(ctx.message.contains('王者荣耀')){

             ctx.tags.add('王者荣耀')

          }

           if(ctx.message.contains('沉溺')){

             ctx.tags.add('沉溺')

          }

       """

     }

   }

 ]

}

POST message_index/_update_by_query?pipeline=add_tags_pipeline

{

 "query": {

   "match_all": {}

 }

}

POST message_index/_search

{

 "size":0,

 "aggs": {

   "terms_aggs": {

     "terms": {

       "field": "tags.keyword"

     }

   }

 }

}

实现后,结果如下:

image.png

这种统计的依然是:关键词(key)和文档(doc_count)的统计关系。


什么意思呢?


"key":“沉溺”,“doc_count”:3 本质含义是:“沉溺”在三个不同的文档中出现了。


细心的读者会发现,文档 1 中“沉溺”出现了2次,这种打 tag 统计是不准确的。


3.3 term vectors 统计

PUT message_index

{

 "mappings": {

   "properties": {

     "message": {

       "type": "text",

       "term_vector": "with_positions_offsets_payloads",

       "store": true,

       "analyzer": "ik_max_word"

     }

   }

 }

}

解释一下:


term_vector: 检索特定文档字段中分词单元的信息和统计信息。


store: 默认未开启存储,需要手动设置为true。


with_positions_offsets_payloads 是Lucene 的参数之一,释义如下:

image.png

可以理解为:存储分词单元(term vector)、位置(Token position)、偏移值(offset)、有效负载(payload,猜测是ES 新增的)。


默认会统计词频信息,默认term information 为true。此外,还有 term statistics 和 field statistics 类型供设置和实现不同的统计,详细内容参考官方文档即可。


https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-termvectors.html


执行:


GET message_index/_termvectors/1?fields=message

后的返回结果如下:

image.png

这种基于特定文档的词频统计是传统意义上我们理解的词频统计。


默认情况下,term vectors是实时的,而不是接近实时的。可以通过将 realtime 参数设置为 false 来更改。实时就意味着可能会有性能问题。


3.4 先分词,后 term vectors 统计

在我担心仅 termvectors 可能带来的性能问题的时候,我想到了如下的解决方案。


前提:写入之前除了存储 message 字段,加了一个分词结果组合字段,该字段每个词用空格做分隔。


message 字段的前置分词需要自己调用 analyzer API 实现。


有了切词后的字段,再做统计会更快。


具体实现如下:


DELETE message_ext_index

PUT message_ext_index

{

 "mappings": {

   "properties": {

     "message_ext": {

       "type": "text",

       "term_vector": "with_positions_offsets_payloads",

       "store": true,

       "analyzer": "whitespace"

     }

   }

 }

}

POST message_ext_index/_bulk

{"index":{"_id":1}}

{"message_ext":"沉溺 于 轻易 获得 高 成就感 的 事情 沉溺 有意 无意 地 寻求 用 很小 付出 获得 很大 huibao 的 偏方 哪怕 huibao 是 虚拟 的"}

GET message_ext_index/_termvectors/1?fields=message_ext

强调一下:message_ext 使用的 whitespace 分词器。


4、小结

关于词频统计,本文给出四种方案。只有第3、4种方案结合termvectors 实现是严格意义上的词频统计,其他两种是词频-文档关系的统计。


考虑到方式3的实时分词可能的性能问题,扩展想到方案4前置分词的方式,能有效提高统计效率。本质也是空间换时间。


你的实战中如何实现的词频统计呢?欢迎留言说一下你的实现方式和思考。


参考

https://titanwolf.org/Network/Articles/Article?AID=7c417f9f-5bde-4519-9bd5-39957d184a07 https://discuss.elastic.co/t/word-count-frequency-per-field/159910 https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-termvectors.html

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
9065 0
使用SSH远程登录阿里云ECS服务器
远程连接服务器以及配置环境
12457 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
19696 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
32727 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
17986 0
使用NAT网关轻松为单台云服务器设置多个公网IP
在应用中,有时会遇到用户询问如何使单台云服务器具备多个公网IP的问题。 具体如何操作呢,有了NAT网关这个也不是难题。
34557 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
24794 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
14681 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
13819 0
+关注
348
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载