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

商城项目中 ES 搜索怎么进行分词优化?

  •  1
     
  •   3country · 257 天前 · 2502 次点击
    这是一个创建于 257 天前的主题,其中的信息可能已经有所发展或是发生改变。
    公司做的商城项目,搜索商品用的 es ,分词器使用的 ik ,在使用 ik_max_word 做搜索的时候查询结果会有些问题

    比如一个商品是 XL 汤锅,搜索锅是查询不到的

    某个商品为 XX 护关节钙片,搜索护肝是可以搜索到的(运营的意思是应该搜索不到)

    有大佬给支个招吗?
    15 条回复    2024-03-16 00:12:48 +08:00
    sss15
        1
    sss15  
       257 天前
    第一个问题,不知道
    按照我的理解 ik_max_word 会将词拆分到最细,所以 XL 汤锅,理应通过锅能搜索到的,插个眼看个答案。

    第二个问题
    护肝 2 个字应该是搜索词也被分词了,所以护肝被拆成了护和肝 ,这个可以通过 2 种方式解决,一种是用 keyword 进行搜索,这样搜索词不会被分词。 另外一种是指定搜索词的分词器为 ik_smart 这样分的词会尽量的少
    ghostwind
        2
    ghostwind  
       257 天前
    1. 第一个问题的话,你看下是不是汤锅变成了一个实体词。

    2. 之前我们做的时候是 case by case 你把护肝作为一个实体词,不允许拆分。

    PS:单字的搜索可以不优化,因为不准
    3country
        3
    3country  
    OP
       257 天前
    @sss15 其实原因就是汤锅没给分词,搜索锅搜索不到,护肝给分成了护和肝
    wu00
        4
    wu00  
       257 天前   ❤️ 1
    es 也有 explain 的自己看一下就知道了
    另外查询时最好也要指定分词器,比如你的关键词是”护肝”,用 A 分词器能分出 3 个词,B 分词器分出 1 个
    1 ,ik_max_word 也无法将"汤锅"拆分出“锅”,自己用_analyze 试下就知道了
    2 ,ik_max_word 可将“护肝”拆分成“护”和“肝”,需要自行维护词库
    3country
        5
    3country  
    OP
       257 天前
    @wu00 对于这种场景各大电商平台也是自己维护词库吗?还是说有自研之类的
    996635
        6
    996635  
       257 天前
    关键词:HMM
    wu00
        7
    wu00  
       257 天前
    大厂咱不知道,肯定没这么简单,应该有搜索引擎团队。
    你这种针对分词器维护一下行业词库,最多再做做 BM25 相关度调优就差不多了..
    3country
        8
    3country  
    OP
       257 天前
    @wu00 BM25 相关度调优是指什么?
    zakokun
        9
    zakokun  
       257 天前   ❤️ 1
    ES 支持指定 tokenizer 做分词测试,你可以指定你们线上用的 tokenizer ,然后把商品名称输入进去,查看返回分词结果.

    按照你给的例子,第一个情况是分词器把你“汤锅”作为一整个 token ,所以用“锅”搜不到;

    第二个情况是分词器拆分出“护”这个 token ,然后你的关键词也拆出了“护”,所以匹配到了。

    规则和搜索匹配方式都需要开发自己去指定,包括匹配度,还有分词器,停用词,词库什么的,要和产品商量好。
    zakokun
        10
    zakokun  
       257 天前
    @zakokun 当然怎么拆还是看你配置,不一样是这样拆分的,你可以用_analyze 接口,带上你的分词器和查询内容,看看把它分成了什么,再对比你的搜索语句
    3country
        11
    3country  
    OP
       257 天前
    @zakokun 感谢,我试试
    chippai
        12
    chippai  
       257 天前
    1. 汤锅是一个词,在 ik-max-word 分完后创建的是一个完整的汤锅索引,所以锅搜不出来
    1.1 将锅加到自定义词典,可以分为汤锅/锅,就可以检索到了
    1.2 对一些单字通过 should 模糊匹配去搜,可以降低一些分值排在后面
    2. 护关节被分为护/关节,护肝分为护/肝,护匹配到了
    2.1 增加护关节、护肝自定义词典,然后使用 ik-smart 去搜索
    通过命令查看 es 是咋分的
    POST _analyze
    {
    "analyzer": "ik_max_word",
    "text": "护关节"
    }
    chippai
        13
    chippai  
       257 天前   ❤️ 1
    2.2 可以先将 query 词使用 match_phrase 函数,然后 should 上 match 函数;增加 match_phrase 的分值权重
    publicWyt
        14
    publicWyt  
       257 天前
    这个时候就要参考一下 PDD 等网站了,搜搜看汤锅,商家的 title 是很大一串的相关锅词汇,目测是为了提高检索的命中,也为了让分词器更精准的分离出关键词,汤锅在_analyze 确实是不会分词到锅,但是平底锅高压锅等乱七八糟的都可以
    matrix1010
        15
    matrix1010  
       257 天前 via iPhone
    商品名这种短字符就别 ik 了,直接单字+2gram
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4572 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 05:35 · PVG 13:35 · LAX 21:35 · JFK 00:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.