所需的jar包云盘地址: 链接:https://pan.baidu.com/s/18RDpdLo1FEPCwahOlOT2kQ
提取码:yco4
Elasticsearch单机版安装
因为这里最开始是用本地虚拟机搭建的,后来又用的阿里云的,所以ip不一致,ip前后不一致,请忽略。如果是使用阿里云的,配置使用内网ip, 注意还要开放所需的端口,在管理台页面配置。(安全规则那)
- 上传到linux,解压 tar -zxvf elasticsearch-7.3.2-linux-x86_64.tar.gz
- 在解压的bin目录下直接启动 ./elasticsearch
- 解决方案:
- groupadd taibai // 创建组
- useradd taibai -g taibai // 为taibai组创建taibai用户
- su root // 切换到root用户
- chown -R taibai:taibai elasticsearch-7.3.2/ // 将elasticsearch 目录赋予 taibai用户
- 进入bin目录下,切换到taibai用户,再次启动,可以启动起来了,但是外网依旧是访问不了的 。
- 解决办法:
- 1)这里为了节省些内存, 内存改的小一下
- 编辑一下 jvm.options -Xms512m 默认为1个g
2) vi elasticsearch.yml
修改的文件:
- 如果是阿里云,这里要配置内网IP
vim /etc/security/limits.conf 修改系统参数,使用root用户, 增加如下内容
- soft nofile 65536
- hard nofile 131072
- soft nproc 2048
- hard nproc 4096
- 所有用户
nofile ‐ 打开文件的最大数目
noproc ‐ 进程的最大数目
soft 指的是当前系统生效的设置值
hard 表明系统中所能设定的最大值
vim /etc/sysctl.conf
vm.max_map_count=655360
sysctl -p 使配置生效
再次启动 ./elasticsearch
外部访问,显示这个结果,表示安装成功了。
- 关闭防火墙
centos7查看防火墙状态
firewall-cmd --state
关闭防火墙 systemctl stop firewalld.service
service iptables stop
永久关闭防火墙
systemctl disable firewalld
chkconfig iptables off
kibana 安装
kibana 用来操作 elasticsearch
- vi kibana.yml
#kibana 访问端口
server.port: 5601
#kibana访问地址,配成本机IP
server.host: "192.168.43.131"
# Enables you to specify a path to mount Kibana at if you are running behind a proxy.
# Use the `server.rewriteBasePath` setting to tell Kibana if it should remove the basePath
# from requests it receives, and to prevent a deprecation warning at startup.
# This setting cannot end in a slash.
#server.basePath: ""
# Specifies whether Kibana should rewrite requests that are prefixed with
# `server.basePath` or require that they are rewritten by your reverse proxy.
# This setting was effectively always `false` before Kibana 6.3 and will
# default to `true` starting in Kibana 7.0.
#server.rewriteBasePath: false
# The maximum payload size in bytes for incoming server requests.
#server.maxPayloadBytes: 1048576
# The Kibana server's name. This is used for display purposes.
#server.name: "your-hostname"
# The URLs of the Elasticsearch instances to use for all your queries.
#配置elasticsearch 的地址,这里是 elasticsearch和kibana 一台机器上,否则就配置elasticsearch的ip
elasticsearch.hosts: ["http://192.168.43.131:9200"]
# kibana 启动改成中文的
i18n.locale: "zh-CN"
- 启动kibana
root用户默认启动不了,不过可以强制启动
- 强制启动 ./kibana --allow-root
- 浏览器访问 192.168.43.131:5601
- 为索引指定 类型,id ,添加数据
- xiaoxu/_doc/id
- 索引名称/类型/id
- id 可以不传,会根据id ,hash散列到 xiaoxu索引的某一个分片上
PUT xiaoxu/_doc/1003
{
"id":"1009",
"sex":"F",
"name":"HNn"
}
- es-head 健康之为黄色,是因为为索引添加了1个副本,但检测到就一个节点,副本和原件都在一个机器上,副本不可用
- 手动发post,为索引修改副本数
PUT /xiaoxu/_settings
{
"number_of_replicas": 0
}
- 依次重置下这几个索引的副本数,结果如下
- 注意, kibana不提供后台启动,Linux可以指定把启动的日志追加到文件中
nohup ./kibana --allow-root &
RESTful API
- 创建空索引
PUT /taibai
{
"settings": {
"number_of_shards": "2", //分片数
"number_of_replicas": "0", //副本数
"write.wait_for_active_shards": 1
}
}
- 删除索引
DELETE /taibai
- 插入数据
//指定id
POST /taibai/_doc/1001
{
"id":1001,
"name":"张三",
"age":20,
"sex":"男"
}
//不指定id es帮我们自动生成
POST /taibai/_doc
{
"id":1002,
"name":"三哥",
"age":20,
"sex":"男"
}
- 更新数据
- 在Elasticsearch中,文档数据是不为修改的,但是可以通过覆盖的方式进行更新
PUT /taibai/_doc/1001
{
"id":1009,
"name":"太白",
"age":21,
"sex":"哈哈"
}
- 局部更新
- 其实es内部对partial update的实际执行和传统的全量替换方式是几乎一样的,其步骤如下
- 内部先获取到对应的document;
- 将传递过来的field更新到document的json中(这一步实质上也是一样的);
- 将老的document标记为deleted(到一定时候才会物理删除);
- 将修改后的新的document创建出来
POST /taibai/_update/1001
{
"doc":{
"age":23
}
}
- 删除数据
DELETE /taibai/_doc/1001
向es中批量导入测试数据
链接:https://pan.baidu.com/s/1AtjdZ1KXSFvpnlh1JunWHA
提取码:jd8l
curl -H 'Content-Type: application/json' -XPOST 'http://101.200.146.11:9200/bank/_bulk?pretty&refresh' --data-binary @accounts.json
1. -H 指定请求头信息 json格式
2. Post请求 地址
3. bank: 创建的索引
4. _bulk :类型
5. accounts.json 文件名
注意: 执行这条命令要在accounts.json的当前目录,注意单引号的问题
- 导入完数据后,就可以看到 新添加的索引了
- 查询数据 GET /bank/_search
6. GET /bank/_doc/6 根据ID 查询记录 get /索引名/类型/id
7. GET /bank/_search 搜索全部数据 get /索引/_search 默认最多返回10条
8. GET /bank/_search?q=age:36 关键字搜索数据
9. POST /bank/_search DSL搜索,查询年纪等于23的
{
"query": {
"match": {
"age": 23
}
}
}
10. GET /bank/_search 查询地址等于mill或者lane
{
"query": {
"match": {
"address": "mill lane"
}
}
}
11. GET /bank/_search 查询地址等于(mill lane)的
{
"query": {
"match_parase": {
"address": "mill lane"
}
}
}
注意:
match 中如果加空格,那么会被认为两个单词,包含任意一个单词将被查询到
match_parase 将忽略空格,将该字符认为一个整体,会在索引中匹配包含这个整体的文档
12. POST /bank/_search 查询age > 20 && gender 为M的文档
{
"query": {
"bool": {
"filter": {
"range": {
"age": {
"gt": 20
}
}
},
"must": {
"match": {
"gender": "M"
}
}
}
}
}
13. POST /bank/_search 高亮显示
{
"query": {
"match": {
"firstname": "Deidre"
}
},
"highlight": {
"fields": {
"firstname": {}
}
}
}
14. POST /bank/_search //聚合操作,类似SQL中的group by操作
{
"aggs": {
"all_interests": {
"terms": {
"field": "age"
}
}
}
}
// 浏览器访问查询bank索引 类型doc, id 为1的文档, ?pretty 并对返回的数据格式化
15. http://101.200.146.11:9200/bank/_doc/1?pretty
// 指定响应的字段
16. GET /bank/_doc/1?_source=email,firstname
// 还可以去掉元数据并且返回指定字段
17. GET /bank/_source/1?_source=email,firstname
18. HEAD /bank/_doc/1 //判断文档是否存在
19. POST /taibai/_mget // 批量查询
{
"ids": ["1001","1002"]
}
20. POST _bulk //批量插入
{"create":{"_index":"taibai","_id":"6"}}
{"id":2002,"name":"大明明","age":25,"sex":"男"}
{"create":{"_index":"taibai","_id":"7"}}
{"id":2003,"name":"小明明","age":29,"sex":"男"}
21. POST _bulk //批量删除
{"delete":{"_index":"taibai","_id":"3"}}
{"delete":{"_index":"taibai","_id":"4"}}
22. POST _bulk //批量更新
{"update":{"_index":"taibai","_id":"6"}}
{"doc":{"name":"张飞"}}
{"update":{"_index":"taibai","_id":"7"}}
{"doc":{"name":"李白"}}
23. GET /taibai/_search?size=2&from=2 //分页查询
映射
前面我们创建的索引以及插入数据,都是由Elasticsearch进行自动判断类型,有些时候我们是需要进行明确字段类
型的,否则,自动判断的类型和实际需求是不相符的
- 自动判断的规则如下:
JSON type | Field type |
---|---|
Boolean: true or false | “boolean” |
Whole number: | 123 “long” |
Floating point: 123.45 | “double” |
String, valid date: “2014-09-15” | “date” |
String: “foo bar” | “string” |
- 创建明确类型的索引:
PUT /goods
{
"settings": {
"number_of_replicas": 0,
"number_of_shards": 1
},
"mappings": {
"properties": {
"id": {
"type": "long"
},
"sn": {
"type": "keyword"
},
"name": {
"type": "text",
"analyzer": "ik_max_word"
},
"price": {
"type": "double"
},
"num": {
"type": "integer"
},
"alert_num": {
"type": "integer"
},
"image": {
"type": "keyword"
},
"images": {
"type": "keyword"
},
"weight": {
"type": "double"
},
"create_time": {
"type": "date",
"format": "yyyy‐MM‐dd HH:mm:ss"
},
"update_time": {
"type": "date",
"format": "yyyy‐MM‐dd HH:mm:ss"
},
"spu_id": {
"type": "keyword"
},
"category_id": {
"type": "integer"
},
"category_name": {
"type": "text",
"analyzer": "ik_smart"
},
"brand_name": {
"type": "keyword"
},
"spec": {
"type": "text",
"analyzer": "ik_max_word"
},
"sale_num": {
"type": "integer"
},
"comment_num": {
"type": "integer"
},
"status": {
"type": "integer"
}
}
}
}
结构化查询
- term 查询
term 主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed 的字符串(未经分析的文本数据类型):
type 类型是text的,默认分词器会将中文分成单个汉子,比如张飞 分成 张、飞
// 这样就导致按name=张三 查询,查询不到, 按 张可以查到
POST /taibai/_search
{
"query": {
"term": {
"name": "张"
}
}
}
// 可以使用name.keywod 查询出连词
POST /taibai/_search
{
"query": {
"term": {
"name.keyword": "张飞"
}
}
}
- terms查询 terms 跟 term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一起去
做匹配
POST /taibai/_search
{
"query" : {
"terms" : {
"age" : [2,29]
}
}
}
- range查询
range 过滤允许我们按照指定范围查找一批数据
gt :: 大于 gte :: 大于等于 lt :: 小于 lte :: 小于等于
POST /taibai/_search
{
"query": {
"range": {
"age": {
"gte": 2,
"lte": 29
}
}
}
}
- exists查询
exists 查询可以用于查找文档中是否包含指定字段或没有某个字段,类似于SQL语句中的 IS_NULL 条件
包含这个字段就返回返回这条数据
POST /taibai/_search
{
"query": {
"exists": {
"field": "name"
}
}
}
- match查询
match 查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它。 如果你使用 match 查询一
个全文本字段,它会在真正查询之前用分析器先分析 match 一下查询字符;如果用 match 下指定了一个确切值,
在遇到数字,日期,布尔值或者 not_analyzed 的字符串时,它将为你搜索你 给定的值
POST /taibai/_search
{
"query" : {
"match" : {
"name" : "三个小矮人"
}
}
}
match查询会先对搜索词进行分词,分词完毕后再逐个对分词结果进行匹配,因此相比于term的精确搜索,match是分词匹配搜索, 比如: 分词后的小字和小明明匹配上,返回小明明这条记录。
- 聚合查询
聚合操作,类似SQL中的group by操作, avg_age 是为 age的平均值取的别名
POST /taibai/_search
{
"aggs": {
"avg_age": {
"cardinality": {
"field": "age"
}
}
}
,"size":0
}
// 按age去重,相当于distinct
POST /taibai/_search
{
"aggs": {
"distinct_age": {
"cardinality": {
"field": "age"
}
}
}
,"size":0
}
分词器
- elasticsearch内置分词器
Standard | 默认分词器 按词分类 小写处理 |
---|---|
Simple | 按照非字母切分,非字母则会被去除 小写处理 |
Stop | 小写处理 停用词过滤(the,a, is) |
Whitespace | 按空格切分 |
Keyword | 不分词,当成一整个 term 输出 |
Patter | 通过正则表达式进行分词 默认是 \W+(非字母进行分隔) |
Language | 提供了 30 多种常见语言的分词器 |
- 分词api
拼音分词器
1.下载对应版本的zip包https://github.com/medcl/elasticsearch-analysis-pinyin/releases
2.可在Windows解压好,在plugins下创建pinyin文件夹
3.将解压内容放置在pinyin文件夹,重启
链接:https://pan.baidu.com/s/1uiW5LqSRbnmD6jBYGcjBuw
提取码:98ed
将ik pinyin 直接置于 elasticsearch 根目录下的plugins 下,重启
- 测试分词器效果 ik 分词器,和默认的standard分词器
POST /_analyze
{
"analyzer":"standard",
"text":"决战到天亮"
}
POST /_analyze
{
"analyzer":"ik_max_word",
"text":"决战到天亮"
}
自定义分词器
- 创建一个中文+拼音的分词器
PUT my_index
{
"settings": {
"analysis": {
"analyzer": {
"ik_pinyin_analyzer": {
"type": "custom",
"tokenizer": "ik_smart",
"filter": [
"pinyin_max_word_filter"
]
},
"ik_pingying_smark": {
"type": "custom",
"tokenizer": "ik_smart",
"filter": [
"pinyin_smark_word_filter"
]
}
},
"filter": {
"pinyin_max_word_filter": {
"type": "pinyin",
"keep_full_pinyin": "true", #分词全拼如雪花 分词xue,hua
"keep_separate_first_letter": "true", #分词简写如雪花 分词xh
"keep_joined_full_pinyin": true #分词会quanpin 连接 比如雪花分词 xuehua
},
"pinyin_smark_word_filter": {
"type": "pinyin",
"keep_separate_first_letter": "false", #不分词简写如雪花 分词不分词xh
"keep_first_letter": "false" #不分词单个首字母 如雪花 不分词 x,h
}
}
}
}
}
// 为my_index 索引添加分词属性
PUT /my_index/_mapping
{
"properties": {
"productName": {
"type": "text",
"analyzer": "ik_pinyin_analyzer", #做文档所用的分词器
"search_analyzer":"ik_pingying_smark" #搜索使用的分词器
}
}
}
// 添加数据
POST /my_index/_doc
{
"productName": "雪花啤酒100L"
}
//查询
GET /my_index/_search
{
"query": {
"match": {
"productName": "雪Hua"
}
}
}