上一章ElasticSearch 连载一 基础入门 对Elastic
的概念、安装以及基础操做进行了介绍。html
那是否是有童鞋会有如下几个问题呢?git
那么接下来就为你们细细道来。github
搜索引擎的核心是 倒排索引 而倒排索引的基础就是分词
。所谓分词能够简单理解为将一个完整的句子切割为一个个单词的过程。在 es 中单词对应英文为 term
。咱们简单看下面例子:shell
我爱北京天安门
ES 的倒排索引便是根据分词后的单词建立,即 我
、爱
、北京
、天安门
这4个单词。这也意味着你在搜索的时候也只能搜索这4个单词才能命中该文档。json
首先,安装中文分词插件。这里使用的是 ik 。segmentfault
./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
的文件。app
接着,从新启动 Elastic
,就会自动加载这个新安装的插件。curl
用下面命令测试一下ik
分词器:elasticsearch
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
中定义了特定字段的分析方式
而后,新建一个 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
算是有一个基本的入门,下一章节将进一步学习分词器的特性以及场景案例。