资讯专栏INFORMATION COLUMN

ElasticSearch 连载二 中文分词

xi4oh4o / 1395人阅读

摘要:什么是中文分词器搜索引擎的核心是倒排索引而倒排索引的基础就是分词。分词器安装首先,安装中文分词插件。这两个字段都是中文,而且类型都是文本,所以需要指定中文分词器,不能使用默认的英文分词器。

上一章ElasticSearch 连载一 基础入门 对Elastic的概念、安装以及基础操作进行了介绍。

那是不是有童鞋会有以下几个问题呢?

什么是中文分词器?

分词器怎么安装?

如何使用中文分词器?

那么接下来就为大家细细道来。

什么是中文分词器

搜索引擎的核心是 倒排索引 而倒排索引的基础就是分词。所谓分词可以简单理解为将一个完整的句子切割为一个个单词的过程。在 es 中单词对应英文为 term。我们简单看下面例子:

我爱北京天安门

ES 的倒排索引即是根据分词后的单词创建,即 北京天安门这4个单词。这也意味着你在搜索的时候也只能搜索这4个单词才能命中该文档。

分词器安装

首先,安装中文分词插件。这里使用的是 ik 。

./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v5.5.1/elasticsearch-analysis-ik-5.5.1.zip

上面代码安装的是5.5.1版的插件,与 Elastic 5.5.1 配合使用。

安装结束后,会发现目录 /elasticsearch-5.5.1/plugins 多了一个analysis-ik 的文件。

接着,重新启动 Elastic ,就会自动加载这个新安装的插件。

最简单的测试

用下面命令测试一下ik分词器:

curl -X GET "http://localhost:9200/_analyze?pretty&analyzer=ik_smart" -d "我爱北京天安门"

返回结果:

{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "爱",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "北京",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "天安门",
      "start_offset" : 4,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 3
    }
  ]
}

那么恭喜你,完成了ik分词器的安装。

如何使用中文分词器 概念

这里介绍下 什么是_all字段, 其实_all字段是为了在不知道搜索哪个字段时,使用的。ES会把所有的字段(除非你手动设置成false),都放在_all中,然后通过分词器去解析。当你使用query_string的时候,默认就在这个_all字段上去做查询,而不需要挨个字段遍历,节省了时间。

properties中定义了特定字段的分析方式

type,字段的类型为string,只有string类型才涉及到分词,像是数字之类的是不需要分词的。

store,定义字段的存储方式,no代表不多带带存储,查询的时候会从_source中解析。当你频繁的针对某个字段查询时,可以考虑设置成true。

term_vector,定义了词的存储方式,with_position_offsets,意思是存储词语的偏移位置,在结果高亮的时候有用。

analyzer,定义了索引时的分词方法

search_analyzer,定义了搜索时的分词方法

include_in_all,定义了是否包含在_all字段中

boost,是跟计算分值相关的。

添加Index

然后,新建一个 Index,指定需要分词的字段。这一步根据数据结构而异,下面的命令只针对本文。基本上,凡是需要搜索的中文字段,都要多带带设置一下。

curl -X PUT "localhost:9200/school" -d "
{
  "mappings": {
    "student": {
        "_all": {
            "analyzer": "ik_max_word",
            "search_analyzer": "ik_max_word",
            "term_vector": "no",
            "store": "false"
        },
      "properties": {
        "user": {
          "type": "text",
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_max_word",
          "include_in_all": "true",
          "boost": 8
        },
        "desc": {
          "type": "text",
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_max_word",
          "include_in_all": "true",
          "boost": 10
        }
      }
    }
  }
}"

上面代码中,首先新建一个名称为school的 Index,里面有一个名称为student的 Type。student有三个字段。

user

desc

这两个字段都是中文,而且类型都是文本(text),所以需要指定中文分词器,不能使用默认的英文分词器。

上面代码中,analyzer是字段文本的分词器,search_analyzer是搜索词的分词器。ik_max_word分词器是插件ik提供的,可以对文本进行最大数量的分词。

数据操作

创建好了Index后,我们来实际演示下:

新增记录
curl -X PUT "localhost:9200/school/student/1" -d "
{
  "user": "许星星",
  "desc": "这是一个不可描述的姓名"
}"
curl -X PUT "localhost:9200/school/student/2" -d "
{
  "user": "天上的星星",
  "desc": "一闪一闪亮晶晶,爸比会跳舞"
}"
curl -X PUT "localhost:9200/school/student/3" -d "
{
  "user": "比克大魔王",
  "desc": "拿着水晶棒,亮晶晶的棒棒。"
}"

返回数据:

{
    "_index": "school",
    "_type": "student",
    "_id": "3",
    "_version": 2,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "created": false
}
全文搜索

Elastic 的查询非常特别,使用自己的查询语法,要求 GET 请求带有数据体。

curl "localhost:9200/school/student/_search"  -d "
{
  "query" : { "match" : { "desc" : "晶晶" }}
}"

上面代码使用 Match 查询,指定的匹配条件是desc字段里面包含"晶晶"这个词。返回结果如下。

{
    "took": 7,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 2,
        "max_score": 2.5811603,
        "hits": [
            {
                "_index": "school",
                "_type": "student",
                "_id": "3",
                "_score": 2.5811603,
                "_source": {
                    "user": "比克大魔王",
                    "desc": "拿着水晶棒,亮晶晶的棒棒。"
                }
            },
            {
                "_index": "school",
                "_type": "student",
                "_id": "2",
                "_score": 2.5316024,
                "_source": {
                    "user": "天上的星星",
                    "desc": "一闪一闪亮晶晶,爸比会跳舞"
                }
            }
        ]
    }
}

Elastic 默认一次返回10条结果,可以通过size字段改变这个设置。

curl "localhost:9200/school/student/_search"  -d "
{
  "query" : { "match" : { "desc" : "晶晶" }},
  "size" : 1
}"

上面代码指定,每次只返回一条结果。

还可以通过from字段,指定位移

curl "localhost:9200/school/student/_search"  -d "
{
  "query" : { "match" : { "desc" : "晶晶" }},
  "size" : 1,
  "from" : 1
}"

上面代码指定,从位置1开始(默认是从位置0开始),只返回一条结果。

逻辑运算

如果有多个搜索关键字, Elastic 认为它们是or关系。

curl "localhost:9200/school/student/_search"  -d "
{
  "query" : { "match" : { "desc" : "水晶棒 这是" }}
}"

返回结果:

{
    "took": 8,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 2,
        "max_score": 5.1623206,
        "hits": [
            {
                "_index": "school",
                "_type": "student",
                "_id": "3",
                "_score": 5.1623206,
                "_source": {
                    "user": "比克大魔王",
                    "desc": "拿着水晶棒,亮晶晶的棒棒。"
                }
            },
            {
                "_index": "school",
                "_type": "student",
                "_id": "1",
                "_score": 2.5811603,
                "_source": {
                    "user": "许星星",
                    "desc": "这是一个不可描述的姓名"
                }
            }
        ]
    }
}

如果要执行多个关键词的and搜索,必须使用布尔查询。

curl "localhost:9200/school/student/_search"  -d "
{
  "query": {
    "bool": {
      "must": [
        { "match": { "desc": "水晶棒" } },
        { "match": { "desc": "亮晶晶" } }
      ]
    }
  }
}"

返回结果:

{
    "took": 24,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 1,
        "max_score": 10.324641,
        "hits": [
            {
                "_index": "school",
                "_type": "student",
                "_id": "3",
                "_score": 10.324641,
                "_source": {
                    "user": "比克大魔王",
                    "desc": "拿着水晶棒,亮晶晶的棒棒。"
                }
            }
        ]
    }
}
总结

本章介绍了分词器的基本概念和使用,至此Elastic算是有一个基本的入门,下一章节将进一步学习分词器的特性以及场景案例。

原文地址

https://github.com/WilburXu/b...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/34523.html

相关文章

  • Elasticsearch集成IK中文分词

    摘要:英文分词对英文更加智能,可以识别单数负数,大小写,过滤例如这个词等。中文分词效果很差。新建索引验证的分词效果中华人民共和国验证的分词效果中华人民共和国待更新 一、安装ik分词器 IK分词器 Github 地址:https://github.com/medcl/elas... 因为我安装的 Elasticsearch 是5.6.9版本,所以对应安装 elasticsearch-ana...

    ernest.wang 评论0 收藏0
  • ElasticSearchElasticSearch安装IK中文分词

    摘要:一编译分词器环境配置下载解压配置环境变量添加如下内容加载环境变量查看版本版本选择与对应版本目前使用的为版本,根据以上对应表得出,应该选择版本版本地址二安装下载源码上传到服务器,进入到该目录下打包打包需要向库 一. 编译IK分词器 1. maven环境配置 下载maven wget http://mirrors.cnnic.cn/apache/maven/maven-3/3.3.9/bi...

    Barrior 评论0 收藏0
  • Elasticsearch 及 IK 中文分词插件安装

    摘要:及中文分词插件安装一安装并配置环境变量由于是使用构建的,所以首先需要安装或更高版本才能运行。下载安装包下载校验文件,并对下载的包进行校验若出现,则通过命令安装命令。 Elasticsearch 及 IK 中文分词插件安装 一、安装Java并配置 JAVA_HOME 环境变量 由于Elasticsearch是使用Java构建的,所以首先需要安装 Java 8 或更高版本 才能运行。所有E...

    legendmohe 评论0 收藏0

发表评论

0条评论

xi4oh4o

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<