
Elasticsearch 8.X 如何动态的为正文添加摘要字段?
1、实战问题
返回指定字段可以用:
那有没有什么办法在返回指定字段的基础上指定返回前50个字符呢?
例如我现在有一个file_data字段,字段长度可能在一千以上并且需要对这个字段分词和检索,目前想指定返回file_data字段的前50字符,请问有没有什么好的方法?
——问题来源:死磕Elasticsearch知识星球 https://t.zsxq.com/052rvJ6q7
2、解决方案探讨
这个问题仅涉及到字符级别的提取,可以将上述问题精简提炼为:“已知正文字段 cont,如何提取前50个字符形成 abstr”, 其实如果是 java 里就一行代码:
python里也是一行代码搞定:
而 Elasticsearch 如何实现呢?
其实,看到这里可能有同学说:“早干什么呢?写入的时候,提前建模好,直接根据 cont 自动生成好 abstr,不就可以了吗?”
但是,这是“事后诸葛亮”的做法,实战环节,大家可能都是有考虑场景不充分的情况。
所以,本文的假设已经写入了数十亿甚至更多的数据,不方便再重新导入数据,只考虑在已有数据的基础上做处理的问题。
多说一句,实际业务环节,摘要的提取可不是简单提取前置字符这么简单,还要考虑语义。语义级别的摘要的提取需要借助:深度神经网络的生成式自动文本摘要,举例:基于BERT实现,基于Seq2Seq+Attention模型改良实现,基于Seq2Seq模型对于长文本会产生数据截断等......
3、Elasticsearch 三种实现方案
基于上面的讨论,仅就字符级别,Elasticsearch 可以有如下几种方案。
- 方案一:基于 script field query 检索实现。
- 方案二:基于 runtime_field 运行时字段实现。
- 方案三:基于 ingest pipeline 预处理更新或者重新导入或 reindex 实现。
3.0 定义数据
有了数据,游刃有余。本文基于 Elasticsearch 8.1.0 实现。
用了“龙哥”数据作为索引,因为“龙哥”活全。
3.1 方案一 script field query
执行效果如下:
3.2 方案二 runtime_field
执行效果如下:
参考知识点:Elasticsearch 运行时类型 Runtime fields 深入详解
3.3 方案三:写入前数据预处理,检索后立得
前置条件:定义预处理管道。
涉及知识点:Elasticsearch 预处理没有奇技淫巧,请先用好这一招!
3.3.1 写入的时候指定缺省管道 default_pipeline
执行效果如下:
3.3.2 批量更新update_by_query 和 预处理管道结合
执行效果如下:
4、小结
如果方便,依然重磅推荐写入前提前建模充分的方式,有了提前建模本文的一切都是多余。
万不得已,推荐本文的方案三。方案一、方案二在数据量极大的情况会性能非常低,使用时慎重一些。
文章转载自公众号:铭毅天下Elasticsearch
