1、写在前面
上一篇文章:
Elasticsearch 1 : https://blog.csdn.net/a__int__/article/details/111593162
上一篇文章主要包含了elasticsearch安装、head安装、Kibana安装。
下一篇文章:
Elasticsearch 3 : https://blog.csdn.net/a__int__/article/details/111644611
2、ES基本概念
ES不仅是一个搜索服务器,它还是一个分布式文档数据库(以json形式储存)。
下面是关系型数据库和es的对比
ES默认的是集群环境,它会把索引分成很多切片存在不同的节点中。
2.1、倒排索引
倒排索引为什么叫倒排索引?
1、它的英文名Inverted index,Inverted翻译为反转、倒立。
2、它区别于正排索引,正排索引:文档 —> 单词,倒排索引:单词 —> 文档。
认识倒排索引之前,先认识一下正排索引:
下面对比正排索引和倒排索引的区别:
例如下面有三个文档a1、a2、a3,内容如下:
文档 | 文档内容 |
---|---|
a1 | 我爱北京 |
a2 | 我爱家乡 |
a3 | 家乡真美 |
es采用的就是倒排索引,它比正排索引快很多。
3、IK分词器插件
3.1、安装
下载:https://github.com/medcl/elasticsearch-analysis-ik/releases
放入es:在es的plugins文件夹下新建ik,把下载的内容解压放到里面去
接下来重启es、kibana、head。
启动es的时候,可以看到ik插件加载进去了
也可以在es的bin目录下,使用命令elasticsearch-plugin list
3.2、使用kabana测试
ik分词器提供了两种分词算法:ik_smart(最少切分)、ik_max_word(最细粒度切分)
先测试ik_smart
访问kabana控制台:http://localhost:5601/
ik_smart(最少切分):
ik_max_word(最细粒度切分):
如上我们看到一句话被按照词典中已有的词进行了拆分
3.3、扩展ik分词字典
找到ik目录的config文件夹下的IKAnalyzer.cfg.xml
我们在这里里面扩展字典
接下来我们在config下新建一个字典文件,新建mydic.dic,在里面新添加一个内容“学ES”
然后将mydic.dic加入IKAnalyzer.cfg.xml,然后重启ES
重启的时候可以看到我们自己写的字典被加载进来了
分词效果
4、ES基础指令
4.1、请求类型
如上我们使用的GET请求
其他请求如下:
4.2、PUT 创建索引/数据
PUT /索引名/类型名/文档id
{请求体}
这个类型名以后可能会被弃用
PUT /test1/type1/1
{
"name": "小明",
"age": 3
}
注意:符号不要写成中文的了
访问http://localhost:9100/就可以看到多了一个索引名
点击数据浏览查看
4.3、ES数据类型
核心数据类型 :
(1)字符串类型: text, keyword
(2)数字类型:long, integer, short, byte, double, float, half_float, scaled_float
(3)日期:date
(4)日期 纳秒:date_nanos
(5)布尔型:boolean
(6)Binary:binary
(7)Range: integer_range, float_range, long_range, double_range, date_range
还有其他数据类型,参考:https://www.cnblogs.com/betterwgo/p/11571275.html
例:手动添加字段类型的PUT
PUT /test2
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "long"
},
"birthday": {
"type": "date"
}
}
}
}
4.4、GET 获取索引/数据
获取一个索引详细信息
创建一个默认类型的文档,并查询
如果你没有为字段配置类型,es会自动匹配
GET获取某一条数据(按条件)
4.5、_cat 查看状态
GET _cat/health 查看健康状态
GET _cat/indices?v 查看索引库版本信息
更多_cat相关指令参考:https://www.cnblogs.com/xing901022/p/5365842.html
4.6、修改数据
第一种方式,直接覆盖
第一种方式有个弊端:如果漏掉了某个字段就没有了
第二种方式,POST
POST /test3/_doc/1/_update
{
"doc": {
"name": "张三"
}
}
4.7、删除数据
DELETE
5、_search
查询里面分词器依旧有效
GET /_search
只返回集群索引中的所有文档
5.1、GET /_search?q=
GET /_search?q=name:小明
查询所有索引中name=小明的数据
GET /test1/_search?q=name:小明
查询索引 test1 中name=小明的数据
如果有“类型”,可以详细到类型下查找
GET /test1/type1/_search?q=name:小明
如果类型是_doc
GET /test3/_search?q=name:张三
使用“,”可以查询多个索引里的数据
GET /test3,test1/_search?q=name:张三
使用“ * ”,可以进行多个匹配(模糊搜索)
GET /t*/_search?q=name:张三
使用“_all”匹配多个索引里的某个类型
GET /_all/type1/_search?q=name:张三
5.2、多样化查询
5.2.1、查询query
query 表示查询
match表示查询条件
使用json构建查询的条件
GET /_all/_search
{
"query": {
"match": {
"name": "张三"
}
}
}
"query"对应的就是查询条件,查出来的是每条数据对应的所有字段。
5.2.2、结果过滤 _source
现在我们加上”_source“,筛选我们想要的字段。
GET /_all/_search
{
"query": {
"match": {
"name": "张三"
}
},
"_source": ["name","age"]
}
"_source"也叫结果过滤
5.2.3、排序sort
GET /_all/_search
{
"query": {
"match": {
"name": "张三"
}
},
"_source": ["name","age"],
"sort": [
{
"age": {
"order": "desc"
}
}
]
}
“order”: “desc” 是降序、“order”: “asc” 是升序。
5.2.4、分页(from、size)
GET /_all/_search
{
"query": {
"match": {
"name": "张三"
}
},
"from": 0,
"size": 1
}
from": 0,从第0个开始。
“size”: 1,每个个数为1个。
5.2.5、bool(与、或、非条件)
must表示所有条件必须要满足(对应and)
GET /_all/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "张三"
}
},
{
"match": {
"age": 20
}
}
]
}
}
}
should表示应该有的条件(对应or)
GET /_all/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"name": "张三"
}
},
{
"match": {
"age": 20
}
}
]
}
}
}
must_not 排除条件
5.2.6、过滤filter
只要年龄为10到40的
GET /test3/_search
{
"query": {
"bool": {
"must_not": [
{
"match": {
"name": "张三"
}
}
],
"filter": [
{
"range": {
"age": {
"gte": 10,
"lte": 40
}
}
}
]
}
}
}
查询年龄大于十岁的
GET /test3/_search
{
"query": {
"bool": {
"must_not": [
{
"match": {
"name": "张三"
}
}
],
"filter": [
{
"range": {
"age": {
"gt": 10
}
}
}
]
}
}
}
关于范围:
符号 | 解释 |
---|---|
eq | 等于 |
ne | 不等于 |
gt | 大于 |
gte | 大于等于 |
lt | 小于 |
lte | 小于等于 |
5.2、分词器的利用
直接用空格 隔开,查询多个词匹配
5.3、_score 分值
_score 表示权重,数值越大匹配度越高
5.4、精确查询与分词
- term 精确查询(利用倒排索引查询+分词)
- match 模糊查询(会使用分词器解析+模糊条件)
在做精确查询之前,我们先建一个索引
PUT testdb
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"desc":{
"type": "keyword"
}
}
}
}
向新索引添加数据
PUT testdb/_doc/1
{
"name": "这是testdb name",
"desc": "这是testdb desc"
}
PUT testdb/_doc/2
{
"name": "这是testdb name",
"desc": "这是testdb desc2"
}
查看我们插入的数据
使用分词器试试
GET _analyze
{
"analyzer": "keyword",
"text": "这是testdb name"
}
keyword 视字符串为一个整体不进行分词处理
standard 标准拆分
这里每使用ik分词器,ik分词器只适合中文
没有的分词,是查不到对应的数据的
keyword要输入完整的内容才能查到
精确查询多个值
5.5、高亮查询highlight
GET test3/_search
{
"query": {
"match": {
"name": "张三"
}
},
"highlight": {
"fields": {
"name": {}
}
}
}
如上图<em>标签是可以改成其他标签的
GET test3/_search
{
"query": {
"match": {
"name": "三"
}
},
"highlight": {
"pre_tags": "<p style='color:red'>",
"post_tags": "</p>",
"fields": {
"name": {}
}
}
}
pre_tags 前缀
post_tags 后缀