1、词频相关实战问题最近词频统计问题被问到的非常多,词频统计问题清单如下:
如上三个问题都可以归结为:Elasticsearch 文档词频统计问题。该问题在检索、统计领域应用的非常多。 那么 Elasticsearch 如何实现词频统计呢?有必要梳理一下。 2、词频统计探讨之前的文章《Elasticsearch词频统计实现与原理解读》,解决的是:Q3 提及的某索引中特定关键词统计的问题。 解决方案是:text 字段开启 fielddata,咱们在《长津湖影评可视化》中词云的可视化本质也是这种方案。 那么,对于给定文档的词频统计呢? 原来开启 fielddata 的方案就可以实现,举例如下: DELETE message_index 无非在聚合的时候,加上query 语句指定了特定 id 进行检索。 这种方法的缺点在于:正如 Q3 所说,聚合效率低。 看过上次直播的同学,可能会闪现一种想法,写入前打 tag 的方式能解决吗? 可以解决,但有个前提。先画个图解释一下: 这个打 tag 的字段非全量,而是特定的指定脚本处理的部分。下一小节详细实现一把。 其实,除了开启 fielddata 和 打 tag 之外,在 Elasticsearch 中有 termvectors 接口也能实现文档词频统计。下一小节一并实现。 3、词频统计实现3.1 text 开启 fielddata 后聚合方案第 2 部分已有实现说明,不再赘述。 3.2 写入前打 tag,写入后聚合统计方案还是用第 2 部分的数据,说明如下: PUT _ingest/pipeline/add_tags_pipeline 实现后,结果如下: 这种统计的依然是:关键词(key)和文档(doc_count)的统计关系。 什么意思呢? "key":“沉溺”,“doc_count”:3 本质含义是:“沉溺”在三个不同的文档中出现了。 细心的读者会发现,文档 1 中“沉溺”出现了2次,这种打 tag 统计是不准确的。 3.3 term vectors 统计PUT message_index 解释一下:
with_positions_offsets_payloads 是Lucene 的参数之一,释义如下: 可以理解为:存储分词单元(term vector)、位置(Token position)、偏移值(offset)、有效负载(payload,猜测是ES 新增的)。 默认会统计词频信息,默认term information 为true。此外,还有 term statistics 和 field statistics 类型供设置和实现不同的统计,详细内容参考官方文档即可。 https://www./guide/en/elasticsearch/reference/current/docs-termvectors.html 执行: GET message_index/_termvectors/1?fields=message 后的返回结果如下: 这种基于特定文档的词频统计是传统意义上我们理解的词频统计。 默认情况下,term vectors是实时的,而不是接近实时的。可以通过将 realtime 参数设置为 false 来更改。实时就意味着可能会有性能问题。 3.4 先分词,后 term vectors 统计在我担心仅 termvectors 可能带来的性能问题的时候,我想到了如下的解决方案。 前提:写入之前除了存储 message 字段,加了一个分词结果组合字段,该字段每个词用空格做分隔。 message 字段的前置分词需要自己调用 analyzer API 实现。 有了切词后的字段,再做统计会更快。 具体实现如下: DELETE message_ext_index 强调一下:message_ext 使用的 whitespace 分词器。 4、小结关于词频统计,本文给出四种方案。只有第3、4种方案结合termvectors 实现是严格意义上的词频统计,其他两种是词频-文档关系的统计。 考虑到方式3的实时分词可能的性能问题,扩展想到方案4前置分词的方式,能有效提高统计效率。本质也是空间换时间。 你的实战中如何实现的词频统计呢?欢迎留言说一下你的实现方式和思考。 参考https:///Network/Articles/Article?AID=7c417f9f-5bde-4519-9bd5-39957d184a07 https://discuss./t/word-count-frequency-per-field/159910 https://www./guide/en/elasticsearch/reference/current/docs-termvectors.html 推荐更短时间更快习得更多干货! 已带领70位球友通过 Elastic 官方认证! 中国仅通过百余人 |
|