商城项目中 ES 搜索怎么进行分词优化? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
3country
V2EX    Elasticsearch

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

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

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

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

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

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

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

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

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

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

    规则和搜索匹配方式都需要开发自己去指定,包括匹配度,还有分词器,停用词,词库什么的,要和产品商量好。
    zakokun
        10
    zakokun  
       2024-03-15 16:31:08 +08:00
    @zakokun 当然怎么拆还是看你配置,不一样是这样拆分的,你可以用_analyze 接口,带上你的分词器和查询内容,看看把它分成了什么,再对比你的搜索语句
    3country
        11
    3country  
    OP
       2024-03-15 16:32:09 +08:00
    @zakokun 感谢,我试试
    chippai
        12
    chippai  
       2024-03-15 16:40:33 +08:00
    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  
       2024-03-15 16:43:20 +08:00   1
    2.2 可以先将 query 词使用 match_phrase 函数,然后 should 上 match 函数;增加 mach_phrase 的分值权重
    publicWyt
        14
    publicWyt  
       2024-03-15 17:24:26 +08:00
    这个时候就要参考一下 PDD 等网站了,搜搜看汤锅,商家的 title 是很大一串的相关锅词汇,目测是为了提高检索的命中,也为了让分词器更精准的分离出关键词,汤锅在_analyze 确实是不会分词到锅,但是平底锅高压锅等乱七八糟的都可以
    matrix1010
        15
    matrix1010  
       2024-03-16 00:12:48 +08:00 via iPhone
    商品名这种短字符就别 ik 了,直接单字+2gram
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2501 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 15:28 PVG 23:28 LAX 08:28 JFK 11:28
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86