V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
doraemon0711
V2EX  ›  Elasticsearch

现在用 ES 还推荐通过分词插件的方式对 query 和 doc 进行处理吗?

  •  
  •   doraemon0711 · 17 天前 · 688 次点击

    最近在搞一个搜索框架,同步不同的业务数据,用 es 提供搜素服务 一开始想把 query 和 doc 的分词、NER 等处理自己通过代码实现一个服务(调用现成的包,例如 hanlp )然后将构建好的 doc 索引 json 存到 mongodb 中,在通过 es connector 的同步数据到 es 中;用户搜索的 query 也通过该服务进行分词等处理,同样在 es 返回搜索结果后还有个排序服务来修正排序

    后来想了一下这么做是不是复杂度有点太高了,现在 es 已经集成了大部分功能,自己开发服务的效果也不一定有保证,是不是直接用 es 自身来做就好了

    想了解一下各位是怎么做的,es 集成的中文分词插件怎么样,以及需要重建索引怎么做比较好(这也是我想把分词外置的原因,可以提高一下重建速度)

    9 条回复    2024-06-11 16:23:39 +08:00
    heihe
        1
    heihe  
       17 天前
    你这样又多依赖了一个组件,可以尝试把分词直接放到你们数据写入服务里面,将分词的结果用空格拼接,es 里面保留空格分词。
    lix7
        2
    lix7  
       17 天前   ❤️ 2
    没必要,重复造轮子了,没太理解这么搞得话你 es 里存的是啥东西。ES 已经把你说的做的七七八八了,包括 doc 分词、query 分词,而且中文分词质量也没啥问题,就算你真的要动分词,也是通过 es 分词插件的方式来搞,而不是外置一个服务。

    索引前置的服务可以有,但作用一般是做 connector 增强,数据组装、清洗这类工作,分词还是要收敛到 ES 内。

    召回前置的 NLP 部分大多是做 query 改写、扩召回的,分词一般不会放里面。

    索引重建的话,ES 一个 reindex 就完事儿了,GB 级数据同集群索引重建也就是分钟级的事情,你的方案反而需要你自己手搓整个 ETL 重建流程,感觉得比 ES 慢一两个数量级。

    业务复杂度不高时,只用粗排就行了,之后再加精排。一开始复杂度还是别太高比较好。
    doraemon0711
        3
    doraemon0711  
    OP
       16 天前
    @heihe 我的想法整体和你一致,就是分词放到 ES 上游,分好的 terms 用空格拼接,ES 内部再用空格分词;只不过我在分词之后额外做一个持久化存储( mongodb ),原因是我不清楚 es 保留全部_source 会不会对性能产生影响,如果只保留部分 field ,添加新 field 并要刷数据是就要用到(省去重新分词的步骤)


    @lix7 其实我主要的问题就是分词要不要从 es 拿出去,一是不清楚分词插件能否满足实际情况,以及维护自定义词典的成本;二是对 query 改写,如果要做实体识别提权等处理,是不是也要先分词才能处理?如果是的话不如就全放到 es 外面来做好了,灵活性还会更高一些,但一想到 es 已经集成了,就比较纠结。
    排序这一块不太确定理解的对不对,我理解的是粗排已经由 es 做了,即 es 的主要作用时召回+粗排。精排则需要自己在外部服务去实现,我想法是每次查询请求召回的数量应该比前端请求的数量要多,比如前端传 20 条,我则是查询 es 返回 1000 条,然后再对这 1000 条数据进行精排并添加缓存。但是需求中往往有用户指定按照某个字段排序的情况,这时是不是和粗排精排就没关系了
    heihe
        4
    heihe  
       15 天前
    @doraemon0711 你的目的是干什么呢?当时我们是大数据场景,集群每天几十亿数据写入,集群 TB 级别数据,分词器做了改造,目的是为了减轻 es 集群 CPU 的压力且 ES 只用来检索,如果你数据量不大,像楼下这种偏电商场景,直接用 ES 本身处理即可,至于实体识别,意图识别这个和 ES 本身分词没什么关系,一般是算法测处理,他们存储好,工程测通过关键词直接去拿。
    doraemon0711
        5
    doraemon0711  
    OP
       12 天前
    @heihe 我的数据到不了每天几十亿,但是每天几百万的写入请求可能是有的,目的实际上也是减轻 es 的压力,顺便不确定 ik 分词的 ik_max_word 模式是否合适(这个倒是次要的)
    不过看你回复的实体识别本身和分词没有关系,是不是可以理解成分词和 NER 是平行两条线,在将 doc 传入 es 前,先通过 NER 提取出关键词然后作为另一个字段额外保存,而文档本身还是在 es 中做分词处理(我一直理解的是 NER 是要基于分词结果做处理)
    heihe
        6
    heihe  
       12 天前
    @doraemon0711 一般在召回之前,会对关键词做意图识别,实体识别的处理,然后拿到这些数据作为召回的条件,这些处理规则一般是算法测的模型在处理,工程这边只是拿到结果,当然具体怎么玩,依据你们公司有无对应的团队呢。
    heihe
        7
    heihe  
       12 天前
    @doraemon0711 你这个规模没必要了,直接放 es 里面就可以了。
    doraemon0711
        8
    doraemon0711  
    OP
       12 天前
    @heihe 大概明白了,是不是可以理解成提高召回更多的是对 query 做处理,而 doc 只需要维护好分词词典就可以了,ik 分词器已经解决了大部分中文分词的情况了
    heihe
        9
    heihe  
       12 天前   ❤️ 1
    @doraemon0711 对的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1101 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 18:22 · PVG 02:22 · LAX 11:22 · JFK 14:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.