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

一行命令让 ElasticSearch 支持中文分词搜索

  •  
  •   macg0406 · 2016-03-25 12:17:02 +08:00 · 5174 次点击
    这是一个创建于 2925 天前的主题,其中的信息可能已经有所发展或是发生改变。

    相信大家在开发博客,在线商城的时候会涉及到搜索功能。而近几年火起来的 ElasticSearch ( ES )凭借其稳定、可靠、快速的实时搜索普遍受到大家的好评,连 Github 、 SoundCloud 也都将 ES 作为其核心搜索组件。

    但是 ES 本身对中文分词和搜索比较局限。因为内置的分析器在处理中文分词时,只有两种方式:一种是单字( unigrams )形式,即简单粗暴的将中文的每一个汉字作为一个词( token )分开;另一种是两字( bigrams )的,也就是任意相邻的两个汉字作为一个词分开。这两种方式都不能很好的满足现在的中文分词需求,进而影响了搜索结果

    举个例子: 假设我们的 index 里面存储了 3 篇 documents 如下:

    | id | content

    | 1 | 美称中国武器商很神秘 花巨资海外参展却一言不发

    | 2 | 在第一界国际锦标赛中 国家代表李雷勇夺冠军

    | 3 | 国武公司近日上市

    • Case 1 :查询“中国”,期望只得到 id 为 1 的 document 。

      用 unigram 的分析器(即默认的 Standard Analyzer )查询结果为 id 1 和 id 2 的 content ; bigram 的分析器(名为 cjk )的结果为 id 1 。 Standard Analyzer 没有给出预期结果是因为它把“中国”切分为“中”、“国” 2 个 token ,因此误给出了 id 2 的结果。

    • Case 2 :查询“国武”这一家公司,期望只得到 id 为 3 的 document 。

      Standard Analyzer 和 cjk 的查询结果都会同时给出 id 1 和 id 3 的 document ,但是 id 1 的 document 中的“国武”并不是所指的公司。

      (注:以上查询均用 query_string )

    因此我们可以发现内置的分析器有它的局限性,并不能满足复杂或者特定的搜索需求。为此,玻森数据开发了一款基于玻森中文分词的 ES 插件( Elasticsearch-Analysis-BosonNLP ),方便大家对中文数据进行更精确的搜索。

    现在已有一些成熟的 ES 中文分词插件,但在分词引擎准确率上,相信 BosonNLP 的中文分词能满足大家不同领域上多样化的需求。有兴趣的朋友可以查看11 款开放中文分词引擎大比拼

    接下来, 3 分钟教会大家如何安装使用玻森 ES 中文分词插件 Beta 版(以 ES 2.2.0 版本为例):

    • 安装

    只需如下一个命令。

    $ sudo bin/plugin install https://github.com/bosondata/elasticsearch-analysis-bosonnlp/releases/download/1.3.0-beta/elasticsearch-analysis-bosonnlp-1.3.0-beta.zip
    

    注:对于其他不同版本的 ES ,只需要在命令里更换对应的插件版本号即可。

    • 使用

    需要在elasticsearch.yml文件中的 analyzer 里配置好玻森 bosonnlp analyzer (需要配置 API_TOKEN 以及分词的参数)。详情解释请查看 Github 上玻森 ES 中文分词的 README

    bosonnlp:
        type: bosonnlp
        API_URL: http://api.bosonnlp.com/tag/analysis
        API_TOKEN: *PUT YOUR API TOKEN HERE*
    

    完成以上步骤之后便可以使用玻森 ES 分词插件了。

    对比之前 Case 2 的查询: 查询“国武”这一家公司,期望只得到 id 为 3 的 document 。玻森 ES 分词插件搜搜结果:

    {
      "took" : 70,
      "timed_out" : false,
      "_shards" : {
        "total" : 5,
        "successful" : 5,
        "failed" : 0
      },
      "hits" : {
          "total" : 1,
          "max_score" : 0.15342641,
          "hits" : [ {
              "_index" : "bosonnlp_test",
              "_type" : "text",
              "_id" : "3",
              "_score" : 0.15342641,
              "_source":
    {
        "content":"国武公司近日上市"
    }
        } ]
      }
    }
    

    当然,如果对分词有特定需求的小伙伴可以在配置里修改对应的参数。目前,玻森数据对于中文分词提供了繁简转换、新词发现等功能,能满足不同领域的搜索需求。

    希望这款插件能提升你的工作效率!

    GitHub上有具体的说明。这里附上例子中索引 document 的 bash 文件以方便测试。

    15 条回复    2016-03-25 18:12:49 +08:00
    unixbeta
        1
    unixbeta  
       2016-03-25 12:18:37 +08:00 via iPhone
    有个问题,如何以.来分词
    cdmaok
        2
    cdmaok  
       2016-03-25 12:25:08 +08:00
    能加到 es 官方的 plugin 库里吗?
    macg0406
        3
    macg0406  
    OP
       2016-03-25 12:31:02 +08:00
    @unixbeta 是说只用点切分吗?比如 “这个.是什么.鬼”分为“这个”, “是什么”, “鬼” 吗
    macg0406
        4
    macg0406  
    OP
       2016-03-25 12:31:37 +08:00
    @cdmaok 正在准备中=)
    br00k
        5
    br00k  
       2016-03-25 12:54:55 +08:00
    在用 ik 。词库 OK 的话,还是很好的。
    EPr2hh6LADQWqRVH
        6
    EPr2hh6LADQWqRVH  
       2016-03-25 13:35:24 +08:00
    analyzer 调用频率那么高,还让人家访问 HTTP ,出这个插件不是坑人么
    EPr2hh6LADQWqRVH
        7
    EPr2hh6LADQWqRVH  
       2016-03-25 13:37:15 +08:00
    用的人多了就成 ddos 了,坑人坑己
    aszxqw
        8
    aszxqw  
       2016-03-25 13:38:38 +08:00
    @avastms 同感。
    windfarer
        9
    windfarer  
       2016-03-25 13:57:08 +08:00
    服务器扛得住嘛。。。
    macg0406
        10
    macg0406  
    OP
       2016-03-25 15:07:11 +08:00
    @windfarer 你猜
    qcloud
        11
    qcloud  
       2016-03-25 15:16:30 +08:00
    @macg0406 你猜我猜你猜不猜
    Outshine
        12
    Outshine  
       2016-03-25 15:56:39 +08:00
    嗷,这个是每次查询之前,还要去你服务器做分词,然后再查询。。。

    好吧,这个不是重点,重点是:怎么收费?
    windfarer
        13
    windfarer  
       2016-03-25 16:02:42 +08:00
    每秒 500 次请求怎么样?@macg0406
    slixurd
        14
    slixurd  
       2016-03-25 16:10:07 +08:00   ❤️ 1
    就算真的分词效果好也不会有人用啊
    一次分词要走一次 HTTP 请求
    做个玩具没关系,做个线上产品一次查询还多一次请求
    如果 index 个百万数据,还用不用工作了.....
    macg0406
        15
    macg0406  
    OP
       2016-03-25 18:12:49 +08:00
    @Outshine 分词和词性标注都是免费的 =)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1549 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 17:04 · PVG 01:04 · LAX 10:04 · JFK 13:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.