文章目录
一.ES的介绍
1.基本概念
分布式全文搜索引擎Elasticsearch
2.特点
- 基于lucene
- 使用简单
- 分布式的 ,
- 基于Restful API(http),
- 支持各种客户端(java,php。。)
- PB级别数据
- 性能好,速度高(近实时)
- 支持集群
- ES处理JSON格式的数据
二.安装ES
1.安装ES
1)下载
https://www.elastic.co/downloads/elasticsearch
正常请求我们应该在linux或者Docker安装,但是现在我们是学习阶段,就在window上面进行安装
2)安装
解压即可
可以修改内存配置
3)启动
bin/elasticsearch.bat
4)测试 -web端口
http://localhost:9200
查询状态
2.安装kibana/(elasticsearch-head)
图形界面客户端
- curl
windows支持 安装查询poster, 如果在linux安装也是可以的 - 火狐的POSTER插件界面
- Kibana --推荐
官方推荐 - 前端head比较屌,可以直接看到shard和replica + postman
安装kibana客户端
1)下载
2)安装
解压即可
3)配置
配置服务器地址,编辑config/kibana.yml,设置elasticsearch.url的值为已启动的ES
3)启动
4)测试
http://localhost:5601
2.2.3 head工具入门+postman
进入head页面 进行安装
1)安装
下载
npm install --时间有点久
npm run start
2)配置
跨域访问
修改 elasticsearch/config/elasticsearch.yml
http.cors.enabled: true
http.cors.allow-origin: “*”
3)使用
三.集群健康状态
针对一个索引,Elasticsearch 中其实有专门的衡量索引健康状况的标志,分为三个等级:
- green,绿色。
这代表所有的主分片和副本分片都已分配。你的集群是 100% 可用的。 - yellow,黄色。
所有的主分片已经分片了,但至少还有一个副本是缺失的。不会有数据丢失,所以搜索结果依然是完整的。不过,你的高可用性在某种程度上被弱化。如果更多的分片消失,你就会丢数据了。所以可把 yellow 想象成一个需要及时调查的警告。 - red,红色。
- 至少一个主分片以及它的全部副本都在缺失中。这意味着你在缺少数据:搜索只能返回部分数据,而分配到这个分片上的写入请求会返回一个异常。如果你只有一台主机的话,其实索引的健康状况也是 yellow,因为一台主机,集群没有其他的主机可以防止副本,所以说,这就是一个不健康的状态,因此集群也是十分有必要的
三.回顾Restful
1.定义
名词表示资源,动词表示操作
四.ES相关概念
1.近实时
2.索引库 index -> 数据库
3.文档类型 type -> 表
4.文档 document -> 表中的一行数据
5.列 field -> 一个document由多个列组成 -> 表中的列
6.集群 -> 包括了多个node(一个es,一台电脑) ,默认名字“elasticsearch”
7.节点 node /一个主机/一个ES -> node 默认启动会加入名字叫 “elasticsearch”的集群
8.shard : 分片 , 一个索引库被分成多个分片,多个分片分散在不同的 node上 -> 像数据库的分库
9.replica : 复制品(从/备) , shard分为 parmary shard 主分片, replica备分片 ,
一个主shard和它的备shard不能再一个node上 , 非一对主shard和备shard是可以在一个node上
主shard数量一旦确定不能修改 ,备shard的数量可以修改
五.文档的CRUD
添加
PUT /索引库/文档类型/文档id
{
json格式的文档内容
}
全局修改
POST /索引库/文档类型/文档id
{
json格式的文档内容
}
局部修改
POST /索引库/文档类型/文档id/_update
{
"doc":{
json格式的文档内容
}
}
删除文档
DELETE /索引库/文档类型/文档id
获取文档
GET /索引库/文档类型/文档id
批量获取
GET _mget
{
"docs":[
{"_index":"crm", "_type":"user"},
{}
]
}
六.文档简单查询
- GET _search 查询所有
- GET /索引库/文档类型/_search?q=name:zs&form=10&size=10
七.DSL查询
GET itsource/employee/_search
{
"query": {
"match_all": {}
},
"from": 20,
"size": 10,
"_source": ["fullName", "age", "email"],
"sort": [{"join_date": "desc"},{"age": "asc"}]
}
八.DSL过滤
过滤的效率比查询的效率高,一般先过滤后查询
GET itsource/employee/_search
{
"query": {
"bool": { //boolQuery 组合查询
// 与(must) 或(should) 非(must not)
"must": [
{
"match": {//matchQuery -> 分词匹配 有点像 like
"name": "hello world"
}
} ,
{"match": {"description": "search" }}
],
"filter": {
"term": { //termQuery -> 单词查询
"username": "haha zs" //精确匹配
}
}
}
},
"from": 20,
"size": 10,
"_source": ["fullName", "age", "email"],
"sort": [{"join_date": "desc"},{"age": "asc"}]
}
九.其他查询
1.标准查询 : match
match查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它。
如果你使用match查询一个全文本字段,它会在真正查询之前用分析器(分词器)先分析查询字符:
{
"query": {
"match": {
"fullName": "Steven King"
}
}
}
2.单词查询:term
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"term": {
"tags": "elasticsearch"
}
}
}
}
}
Terms搜索与过滤
{
"query": {
"terms": {
"tags": ["jvm", "hadoop", "lucene"],
"minimum_match": 2
}
}
}
minimum_match:至少匹配个数,默认为1
3.组合查询:bool
{
"query": {
"bool": {
"must": [
{
"match": {
"username": "zs "
}
}
],
"filter": {
"term": {
"age": "18"
}
}
}
},
"from": 0,
"size": 10,
"sort": {"id":"desc"}
}
4.范围查询:range
range过滤允许我们按照指定范围查找一批数据:
{
"query":{
"range": {
"age": {
"gte": 20,
"lt": 30
}
}
}
}
上例中查询年龄大于等于20并且小于30。
gt:> gte:>= lt:< lte:<=
5.是否存在: exists 和 missing
{
"query": {
"bool": {
"must": [{
"match_all": {}
}],
"filter": {
"exists": { "field": "gps" }
}
}
}
}
提示:exists和missing只能用于过滤结果。
6.前缀匹配:prefix
和term查询相似,前匹配搜索不是精确匹配,而是类似于SQL中的like ‘key%’
{
"query": {
"prefix": {
"fullName": "倪"
}
}
}
上例即查询姓倪的所有人。
7.通配符: wildcard ,使用 * 多个,?一个
使用*代表0~N个,使用?代表1个。
{
"query": {
"wildcard": {
"fullName": "倪*华"
}
}
}
十.分词器
安装分词器
ES默认对英文文本的分词器支持较好,但和lucene一样,
如果需要对中文进行全文检索,那么需要使用中文分词器,
同lucene一样,在使用中文全文检索前,需要集成IK分词器。
ES的IK分词器插件源码地址:`https://github.com/medcl/elasticsearch-analysis-ik`
① Maven打包IK插件
② 解压target/releases/elasticsearch-analysis-ik-5.2.2.zip文件
并将其内容放置于ES根目录/plugins/ik
③ 配置插件:(不需要)
插件配置:plugin-descriptor.properties
④ 分词器(可默认)
词典配置:config/IKAnalyzer.cfg.xml
⑤ 重启ES和图形化工具(kibana)
⑥ 测试分词器
POST _analyze
{
"analyzer":"ik_smart",
"text":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"
}
注意:IK分词器有两种类型,分别是ik_smart分词器和ik_max_word分词器。
- ik_smart:
会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”。 - ik_max_word:
会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合;
十.映射
1.基本字段类型
字符串: text (分词), keyword(不分词)
① 针对单个类型的映射配置方式–掌握
查询映射类型:
GET shop/goods/_mapping
修改映射类型
(1)Delete shop;
(2)PUT shop;
```java
(3)POST shop/goods/_mapping
{
"goods": {
"properties": {
"price": {
"type": "integer"
},
"name": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "ik_smart"
}
}
}
}
(4)加入数据
put shop/goods/1
{
"price":88,
"name": "iphone8"
}
配置全局映射
在实际应用场景中,一个对象的属性中,需要全文检索的字段较少,大部分字符串不需要分词,因此,需要利用全局模板覆盖自带的默认模板:
PUT _template/global_template //创建名为global_template的模板
{
"template": "*", //匹配所有索引库
"settings": { "number_of_shards": 1 }, //匹配到的索引库只创建1个主分片
"mappings": {
"_default_": {
"_all": {
"enabled": false //关闭所有类型的_all字段
},
"dynamic_templates": [
{
"string_as_text": {
"match_mapping_type": "string",//匹配类型string
"match": "*_text", //匹配字段名字以_text结尾 a_text
"mapping": {
"type": "text",//将类型为string的字段映射为text类型
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word",
"fields": {
"raw": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
{
"string_as_keyword": { a
"match_mapping_type": "string",//匹配类型string
"mapping": {
"type": "keyword"//将类型为string的字段映射为keyword类型
}
}
}
]
}
}}
上面的意思:就是如果索引库里面字段 以_text结尾 就需要进行分词,如果不是,就不分词
测试:
(1)拷贝上面代码执行
(2)删除库 delete shop
(3)创建库 put shop
(4)加入数据测试
POST shop/goods/5
{
“id”:12,
“name_text”:”iphone x”,
“local“:”cnsssss”
}
代码实例:
GET _search
1. 创建文档 PUT /_index/_type/id
PUT /aisell/user/1
{
"id":1,
"username":"zsii",
"age":18
}
2. 创建文档(内置id) AXAaNVVgQ_BfUQx6M1Be
POST /aisell/user
{
"id":2,
"username":"君君",
"age":38
}
3. 获取文档
GET /aisell/user/1
GET /aisell/user/AXAaNVVgQ_BfUQx6M1Be
返回文档的部分字段
GET /aisell/user/1?_source=username
只返回文档内容,不要元数据
GET /aisell/user/1/_source
4.修改文档
POST /aisell/user/1
{
"username":"pp",
"age":10
}
局部 局部修改
POST /aisell/user/1/_update
{
"doc":{
"username":"ee"
}
}
5. 删除 删除文档
DELETE /aisell/user/1
6. 批量 批量操作
POST _bulk
{ "delete": { "_index": "luo", "_type": "employee", "_id": "1" }}
{ "create": { "_index": "luo", "_type": "blog", "_id": "1" }}
{ "title": "我发布的第一篇博客" }
{ "index": { "_index": "luo", "_type": "blog" }}
{ "title": "我的第二博客" }
7. 批量 批量获取
GET _mget
{
"docs":[
{
"_index":"luo",
"_type":"blog",
"_id":1
},{
"_index":"aisell",
"_type":"user",
"_id":1
}
]
}
方式二 同一个索引库的同一个类型下
GET /aisell/user/_mget
{
"ids" : [ "1", "2" ]
}
8. 分页
GET /aisell/_search?from=0&size=3
9. 字符串 字符串查询
GET /crm/user/_search?q=age:18
10.DSL 查询
GET aisell/user/_search
{
"query":{
"match_all":{}
},
"from":0,
"size":10,
"_source":["username"],
"sort":{"id": "desc"}
}
GET aisell/user/_search
{
"query":{
"match":{
"username":"zsii"
}
},
"from":0,
"size":10,
"_source":["username","age"],
"sort":{"age":"asc"}
}
11.DSL 查询 查询过滤
需求 查询 username 有 zs , age 为 18 ,第一页 每页10条 , 按照age倒叙
GET /qq/ww/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"username": "zs "
}
}
],
"filter": {
"term": {
"age": "18"
}
}
}
},
"from": 0,
"size": 10,
"sort": {"id":"desc"}
}
PUT /qq/ww/4
{
"id":4,
"username":"zs kk",
"age":18
}
测试分词器
POST _analyze
{
"analyzer":"ik_max_word",
"text":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"
}
12. 查看 映射 , 文档字段的类型
GET _mapping
GET /qq/ww/_mapping
13. 文档 文档映射
PUT aa
PUT /aa/bb/_mapping
{
"bb":{
"properties":{
"id":{
"type":"long"
},
"name":{
"type":"text",
"analyzer":"ik_smart",
"search_analyzer": "ik_smart"
}
}
}
}
GET aa/bb/_mapping
14. 全局 全局映射
PUT _template/global_template
{
"template": "*",
"settings": { "number_of_shards": 1 },
"mappings": {
"_default_": {
"_all": {
"enabled": false
},
"dynamic_templates": [
{
"string_as_text": {
"match_mapping_type": "string",
"match": "*_text",
"mapping": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word",
"fields": {
"raw": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
{
"string_as_keyword": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
]
}
}}
PUT cc/dd/1
{
"id":1,
"title":"index"
}
PUT /ee/ff/2
{
"id":2,
"title_text":"admin"
}
title_text -> 分词 text
title_text.raw 不 不分词
GET /cc/dd/_mapping
GET /ee/ff/_mapping