一、ES安装
centos7:
vim /etc/security/limits.conf
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 65536
vim /etc/sysctl.conf
vm.max_map_count=262144
重启三台cdh机器
tar -zxvf elasticsearch-6.6.0.tar.gz -C /opt/module/
tar -zxvf kibana-6.6.0-linux-x86_64.tar.gz -C /opt/module/
vim /opt/module/elasticsearch-6.6.0/config/elasticsearch.yml
cluster.name: my-es
node.name: node-1
bootstrap.memory_lock: false
bootstrap.system_call_filter: false
network.host: cdh01
discovery.zen.ping.unicast.hosts: ["cdh01", "cdh02", "cdh03"]
集群名称,同一集群名称必须相同
单个节点名称 不能一样
分发到其他两台机器上:
scp -r elasticsearch-6.6.0/ root@cdh03:`pwd`
scp -r elasticsearch-6.6.0/ root@cdh032`pwd`
修改其它两台机器的elasticsearch.yml的node.name、network.host
groupadd elsearch
useradd elsearch -g elsearch
chown -R elsearch:elsearch /opt/module/elasticsearch-6.6.0
单机一台启动试一试:
/opt/module/elasticsearch-6.6.0/bin/elasticsearch
直接退出控制台即可退出进程
三台其进行后台启动:
/opt/module/elasticsearch-6.6.0/bin/elasticsearch >/dev/null 2>&1 &
关闭:
ps -ef | grep /opt/module/elasticsearch-6.6.0 |grep -v grep|awk '{print \$2}'|xargs kill
记住,不要用root用户去启动,否则又要修改权限。
curl http://cdh02:9200/_cat/nodes?v
出现了上面的图,说明启动已经成功了。
vim /opt/module/kibana-6.6.0-linux-x86_64/config/kibana.yml
server.host: "cdh01"
elasticsearch.hosts: ["http://cdh01:9200"]
后台启动:
/opt/module/kibana-6.6.0-linux-x86_64/bin/kibana >/dev/null 2>&1 &
访问地址:
二、ES基本概念
对应关系:
查询各个节点状态:
GET /_cat/nodes?v
查询各个索引状态:
GET /_cat/indices?v
es 中会默认存在一个名为.kibana的索引
表头的含义
health green(集群完整) yellow(单点正常、集群不完整) red(单点不正常)
status 是否能使用
index 索引名
uuid 索引统一编号
pri 主节点几个
rep 从节点几个
docs.count 文档数
docs.deleted 文档被删了多少
store.size 整体占空间大小
pri.store.size 主节点占
查询某个索引的分片情况 :
GET /_cat/shards/xxxx
PUT customer2020/_doc/1
{
"id":"0101",
"name":"zhangshan"
}
结果:
{
"_index" : "customer2020",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
默认10片数据,5+5x1:
查看分片:
GET /_cat/shards/customer2020/?v
结果:
查看集群健康:
GET /_cat/health?v
2.1 存储结构
在java中的数据:
public class Movie {
String id;
String name;
Double doubanScore;
List<Actor> actorList;
}
public class Actor{
String id;
String name;
}
在es中,是不会像mysql一样存储它们之间的关联关系的:
{
"id":"1",
"name":"operation red sea",
"doubanScore":"8.5",
"actorList":[
{"id":"1","name":"zhangyi"},
{"id":"2","name":"haiqing"},
{"id":"3","name":"zhanghanyu"}
]
}
三、基本操作
增加一个索引:
PUT /movie_index
2.3 删除一个索引
ES 是不删除也不修改任何数据的,而是增加版本号
DELETE /movie_index
2.4 新增文档
1、 格式 PUT /index/type/id
PUT /movie_index/movie/1
{ "id":1,
"name":"operation red sea",
"doubanScore":8.5,
"actorList":[
{"id":1,"name":"zhang yi"},
{"id":2,"name":"hai qing"},
{"id":3,"name":"zhang han yu"}
]
}
PUT /movie_index/movie/2
{
"id":2,
"name":"operation meigong river",
"doubanScore":8.0,
"actorList":[
{"id":3,"name":"zhang han yu"}
]
}
PUT /movie_index/movie/3
{
"id":3,
"name":"incident red sea",
"doubanScore":5.0,
"actorList":[
{"id":4,"name":"zhang chen"}
]
}
如果之前没建过index或者type,es 会自动创建。
2.5 直接用id查找
GET movie_index/movie/1
2.6 修改—整体替换
PUT和POST都是修改操作,但是PUT会整体替换,POST会替换某一个字段,PUT是幂等性操作,POST是非幂等性操作
和新增没有区别 要求:必须包括全部字段
PUT /movie_index/movie/3
{
"id":"3",
"name":"incident red sea",
"doubanScore":"5.0",
"actorList":[
{"id":"1","name":"zhang chen"}
]
}
2.7修改—某个字段
POST movie_index/movie/3/_update
{
"doc": {
"doubanScore":"7.0"
}
}
2.8 删除一个document
DELETE movie_index/movie/3
2.9 搜索type全部数据
GET movie_index/movie/_search
结果
{
"took": 2, //耗费时间 毫秒
"timed_out": false, //是否超时
"_shards": {
"total": 5, //发送给全部5个分片
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 3, //命中3条数据
"max_score": 1, //最大评分
"hits": [ // 结果
{
"_index": "movie_index",
"_type": "movie",
"_id": 2,
"_score": 1,
"_source": {
"id": "2",
"name": "operation meigong river",
"doubanScore": 8.0,
"actorList": [
{
"id": "1",
"name": "zhang han yu"
}
]
}
。。。。。。。。
。。。。。。。。
}
2.10 按条件查询(全部)
GET movie_index/movie/_search
{
"query":{
"match_all": {}
}
}
2.11 按分词查询
GET movie_index/movie/_search
{
"query":{
"match": {"name":"operation red sea"}
}
}
它会查询出三条数据,因为是分词查询的,所以三个分词在三条数据中都存在。
2.12 按分词子属性查询
GET movie_index/movie/_search
{
"query":{
"match": {"actorList.name":"zhang"}
}
}
精准查询
GET movie_index/movie/_search
{
"query":{
"term": {"actorList.name.keyword":"zhang han yu"}
}
}
会查询出值相等的数据,注意使用的是term和keyword
text类型是专用的分词字段、keyword是不分词字段(精准过滤)
2.13 match phrase
GET movie_index/movie/_search
{
"query":{
"match_phrase": {"name":"operation red"}
}
}
按短语查询,不再利用分词技术,直接用短语在原始数据中匹配
2.14 fuzzy查询(容错匹配,运行错误字母)
GET movie_index/movie/_search
{
"query":{
"fuzzy": {"name":"rad"}
}
}
校正匹配分词,当一个单词都无法准确匹配,es通过一种算法对非常接近的单词也给与一定的评分,能够查询出来,但是消耗更多的性能。
2.15 过滤–查询后过滤
GET movie_index/movie/_search
{
"query":{
"match": {"name":"red"}
},
"post_filter":{
"term": {
"actorList.id": 3
}
}
}
2.16 过滤–查询前过滤(推荐使用)
GET movie_index/movie/_search
{
"query":{
"bool":{
"filter":[ {"term": { "actorList.id": "1" }},
{"term": { "actorList.id": "3" }}
],
"must":{"match":{"name":"red"}}
}
}
}
2.17 过滤–按范围过滤
GET movie_index/movie/_search
{
"query": {
"bool": {
"filter": {
"range": {
"doubanScore": {"gte": 8}
}
}
}
}
}
关于范围操作符:
gt 大于
lt 小于
gte 大于等于 great than or equals
lte 小于等于 less than or equals
2.18 排序
GET movie_index/movie/_search
{
"query":{
"match": {"name":"red sea"}
}
, "sort": [
{
"doubanScore": {
"order": "desc"
}
}
]
}
2.19 分页查询
GET movie_index/movie/_search
{
"query": { "match_all": {} },
"from": 1,
"size": 1
}
2.20 指定查询的字段
GET movie_index/movie/_search
{
"query": { "match_all": {} },
"_source": ["name", "doubanScore"]
}
2.21 高亮
GET movie_index/movie/_search
{
"query":{
"match": {"name":"red sea"}
},
"highlight": {
"fields": {"name":{} }
}
}
2.22 聚合
取出每个演员共参演了多少部电影
GET movie_index/movie/_search
{
"aggs": {
"groupby_actor": {
"terms": {
"field": "actorList.name.keyword"
}
}
}
}
groupby_actor
:这个是名字,随便填。
每个演员参演电影的平均分是多少,并按评分排序
GET movie_index/movie/_search
{
"aggs": {
"groupby_actor_id": {
"terms": {
"field": "actorList.name.keyword" ,
"order": {
"avg_score": "desc"
}
},
"aggs": {
"avg_score":{
"avg": {
"field": "doubanScore"
}
}
}
}
}
}
text类型的字段是不允许进行分组的,keyword类型的才行。
聚合时为何要加 .keyword后缀?
.keyword 是某个字符串字段,专门储存不分词格式的副本 ,在某些场景中只允许只用不分词的格式,比如过滤filter 比如 聚合aggs, 所以字段要加上.keyword的后缀。