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

关于 elasticsearch 分词的疑问求解?

  •  
  •   lovepim · 2017-03-12 22:17:18 +08:00 · 3348 次点击
    这是一个创建于 2813 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题是这样的:

    1 、之前用 elasticsearch 导入了一些数据,都是找来的客户邮箱,几百万吧。导入的时候,没注意分词,也就是默认了标准模式。后来查询用的 kibana ,因为不需要分词,所以每次查询都是用的双引号把关键词括起来的。

    2 、最近需要开发一个 php 检索 elasticsearch 的接口,还是不需要分词,但是怎么都实现不了,甚至我用了双赢号把关键词括起来都不行,就像这样的:$key='"'.$getkey.'"',它还是会传给 elastic 分词查询。

    3 、后来查了文档,原因是 elastic 和 kibana 都采用了 lucene 的全文搜索规则。

    4 、所以,问题就是,现在没办法改 mapping 的情况下,怎么才能让这个 php 接口不分词检索?

    大大的求助啊!

    14 条回复    2017-04-25 17:24:32 +08:00
    knightdf
        1
    knightdf  
       2017-03-12 22:36:34 +08:00
    1, 用 term query
    2 ,指定 search analyzer
    lovepim
        2
    lovepim  
    OP
       2017-03-12 22:46:35 +08:00
    @knightdf
    多谢回答!请问具体改哪里?这是用的网上写好的类,我不是特别熟悉:
    这是 class 代码:
    public function search($data) {
    $url = 'http://' . $this->host . ':' . $this->port . '/' . $this->indexName . '/' . $this->tableName . '/_search';
    $json_data = json_encode ( $data );
    return $this->curl ( $url, $json_data, "GET" );
    }

    这是引用代码:
    $elasticsearch = new \Think\ElasticsearchService ();
    $index['query']['bool']['should'] = array(
    array('match' => array('Address' => $keyword)),
    array('match' => array('Email' => $keyword))
    );

    $result= $elasticsearch->search ( $index );
    knightdf
        3
    knightdf  
       2017-03-12 22:52:50 +08:00
    @lovepim 不会 PHP ,我改个样子你去琢磨:
    $index['query']['bool']['must'] = array(
    array('match' => array('Address' => $keyword)),
    array('term' => array('Email' => $keyword))
    );
    billzhuang
        4
    billzhuang  
       2017-03-12 22:53:30 +08:00
    最简单的办法是,导入的数据用 logstash ,并且将 index 的名字以 logstash_开头,会自动帮你做好大部分事情。

    比如你这个问题,是这么解决的,假设你的字段叫 email ,那么 email 这个字段是帮你分词好的,但还会有个叫 email.raw 的字段,就是没分词的。
    knightdf
        5
    knightdf  
       2017-03-12 23:00:27 +08:00
    @lovepim 或者:
    $index['query']['bool']['should'] = array(
    array('match' => array('Address' => $keyword)),
    array('match' => array('Email' => ('query' => $keyword, 'analyzer' => 'whitespace')))
    );
    lovepim
        6
    lovepim  
    OP
       2017-03-12 23:07:15 +08:00
    @knightdf
    哈哈,好像不行啊,直接跑死了。
    lovepim
        7
    lovepim  
    OP
       2017-03-12 23:12:05 +08:00
    @knightdf
    第二段代码加上以后,搜一个邮箱 [email protected] ,不光是 @分词了,连后面的.也分了。之前是光 @分词。
    lovepim
        8
    lovepim  
    OP
       2017-03-12 23:14:48 +08:00
    @billzhuang
    我的数据当时就是用 logstash 导入的,自动建的 mapping 。。。现在没有原数据了,不能重新导了。
    lgpqdwjh
        9
    lgpqdwjh  
       2017-03-12 23:17:15 +08:00
    @lovepim 不懂 php , 可以把数据都导出来, 梳理一下 重新导入进去, 再查询

    理论上 term query 是可以实现的
    slixurd
        10
    slixurd  
       2017-03-12 23:20:53 +08:00
    新手的话就好办了,反正_source 肯定没关....
    拿_source 重建一个索引就完了,源数据都在,几百万数据也就几十分钟的事情
    分完词了拿 term query 查个啥....
    knightdf
        11
    knightdf  
       2017-03-12 23:54:44 +08:00
    @lovepim whitespace 是不会分 @和.的
    rrfeng
        12
    rrfeng  
       2017-03-13 00:09:31 +08:00 via Android
    分词有两种,索引数据的时候和查询的时候。

    都要搞定才行。
    Jakesoft
        13
    Jakesoft  
       2017-03-13 00:17:22 +08:00
    @knightdf 你这个 match 查询是可以的,但是 term 查询似乎只对 not analyzed 字段有用,他这估计肯定是用了用了默认的 analyzer
    alexanderchen
        14
    alexanderchen  
       2017-04-25 17:24:32 +08:00
    索引时候用细粒度的分词策略,查询时候用粗粒度的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2431 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 02:09 · PVG 10:09 · LAX 18:09 · JFK 21:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.