ElasticSearch环境学习

本文详细介绍了如何在Docker上部署Elasticsearch和Kibana,包括下载镜像、创建数据挂载目录、配置文件及启动服务。还讲解了Elasticsearch的基本操作,如查看健康状态、节点信息、索引管理和数据增删改查。同时,讨论了乐观锁的概念,以及如何执行批量操作和搜索查询。此外,还提到了索引映射的管理和IK分词器的配置。内容涵盖了Elasticsearch的基础操作和实际应用。
摘要由CSDN通过智能技术生成

环境搭建

docker 上部署环境

# 下载elasticsearch
docker pull elasticsearch:7.4.2

# 可视化es 监控
docker pull kibana:7.4.2

# 创建文件夹(数据挂载使用)
mkdir -p /mydata/elasticsearch/config
mkdir -p /mydata/elasticsearch/data

# 文件elasticsearch.yml插入  -->  http.host: 0.0.0.0
echo "http.host: 0.0.0.0" > /mydata/elasticsearch/config/elasticsearch.yml

# 修改权限
chmod -R 777 /mydata/elasticsearch/

# 启动es
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e  "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v  /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2

# 开机自启
docker update elasticsearch --restart=always

# 启动kibana
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.56.10:9200 -p 5601:5601 -d kibana:7.4.2

# 开机自启
docker update kibana --restart=always

ui 页面

  • 访问elasticsearch

http://192.168.56.10:9200/

  • 访问kibana

http://192.168.56.10:5601/

使用基本语法

基本请求

# 查看健康状态
http://192.168.56.10:9200/_cat/health

# 查看节点信息
http://192.168.56.10:9200/_cat/nodes

# 查看主节点信息
http://192.168.56.10:9200/_cat/master

# 查看所有索引
http://192.168.56.10:9200/_cat/indices

基本增删改查

get 查询

http://192.168.56.10:9200/costomer/external/3 

{	"_index": "costomer",          	// 那个索引下
	"_type": "external",           	// 索引类型
	"_id": "1",                     // 索引分类下id
	"_version": 2,                  // 版本 (2更新一次)
	"_seq_no": 1,                   // 乐观锁使用(操作数据+1)
	"_primary_term": 1,             // 同上,主分片重新分配,如重启就会发生变化
	"found": true,                  // 找到数据 true
	"_source": {                    // 真正查询数据
		"name": "jack"
	}
}

post put 新增 post put 修改都能为之前对象增加属性

http://192.168.56.10:9200/costomer/external/3
{
  "name":"张三"
}
post 
		带id 有数据就修改,没有数据就是更新
		不带id就是新增 随机生成id

put
		带id 有数据就修改,没有数据就是更新
		不带id  错误码406  没有对应的请求

模拟高并发 乐观锁

使用了乐观锁,修改不成功错误码 409

  • http://192.168.56.10:9200/costomer/external/1?if_seq_no=1&if_primary_term=1
{
  "name":"111"
}
  • http://192.168.56.10:9200/costomer/external/1?if_seq_no=1&if_primary_term=1
{
  "name":"222"
}

同时修改比较 seq_no primary_term

修改用 _update

http://192.168.56.10:9200/costomer/external/3/_update

//json 格式必须是 {"doc":{主体}}
{
	"doc": {
		"name": "123"
	}
}

​ 会与原来数据对比 数据一致 (version和_seq_no)都不变

不带update 参数
{
  "name":"123456"
}
每次都会更改成功

删除

删除指定id

http://192.168.56.10:9200/costomer/external/1

删除成功: result:deleted
删除失败: result:not_found

​ 删除整个索引

http://192.168.56.10:9200/costomer

成功:{“acknowledged”: true}
失败:error 状态404

路径格式不能是

http://192.168.56.10:9200/costomer/external

以下测试均在kibana下测试

批量

语法

{action:{metadata}}\n
{request body  }\n

{action:{metadata}}\n
{request body  }\n
执行多条数据
POST customer/external/_bulk
{"index":{"_id":"1"}}  //标识
{"name":"John Doe"}	   //数据
{"index":{"_id":"2"}}
{"name":"John Doe"}
  • 这里的批量操作,当发生某一条执行发生失败时,其他的数据仍然能够接着执行,也就是说彼此之间是独立的。

    bulk api以此按顺序执行所有的action(动作)。如果一个单个的动作因任何原因失败,它将继续处理它后面剩余的动作。当bulk api返回时,它将提供每个动作的状态(与发送的顺序相同),所以您可以检查是否一个指定的动作是否失败了。

对于整个索引执行批量操作
POST /_bulk
{"delete":{"_index":"website","_type":"blog","_id":"123"}}  
{"create":{"_index":"website","_type":"blog","_id":"123"}}
{"title":"my first blog post"}
{"index":{"_index":"website","_type":"blog"}}
{"title":"my second blog post"}
{"update":{"_index":"website","_type":"blog","_id":"123"}}
{"doc":{"title":"my updated blog post"}}
  • 运行结果
{
  "took" : 608,        // 执行时间
  "errors" : false,	   // 异常
  "items" : [		  // 执行块
    {
      "delete" : { 
        "_index" : "website",
        "_type" : "blog",
        "_id" : "123",
        "_version" : 1,
        "result" : "not_found",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 404		//执行失败
      }
    },
    {
      "create" : {
        "_index" : "website",
        "_type" : "blog",
        "_id" : "123",
        "_version" : 2,		//版本
        "result" : "created",	//什么操作
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 1,
        "_primary_term" : 1,
        "status" : 201		//成功
      }
    },
    {
      "index" : {
        "_index" : "website",
        "_type" : "blog",
        "_id" : "MCOs0HEBHYK_MJXUyYIz",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 2,
        "_primary_term" : 1,
        "status" : 201
      }
    },
    {
      "update" : {
        "_index" : "website",
        "_type" : "blog",
        "_id" : "123",
        "_version" : 3,
        "result" : "updated",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 3,
        "_primary_term" : 1,
        "status" : 200
      }
    }
  ]
}

官方提供的测试数据

执行 : POST bank/account/_bulk

​ 数据

检索

search Api

ES支持两种基本方式检索;

  • 通过REST request uri 发送搜索参数 (uri +检索参数);
  • 通过REST request body 来发送它们(uri+请求体);

uri+请求参数

GET bank/_search?q=*&sort=account_number:asc

uri+请求体进行检索

GET /bank/_search
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" },
    {"balance":"desc"}
  ]
}

详情字段信息

  • took – Elasticsearch运行查询多长时间(以毫秒为单位)
  • timed_out –搜索请求是否超时
  • _shards –搜索了多少个分片,以及成功,失败或跳过了多少个分片。
  • max_score –找到的最相关文件的分数
  • hits.total.value -找到了多少个匹配的文档
  • hits.sort -文档的排序位置(不按相关性得分排序时)
  • hits._score-文档的相关性得分(使用时不适用match_all

Query DSL

基本语法格式

Elasticsearch提供了一个可以执行查询的Json风格的DSL。这个被称为Query DSL,该查询语言非常全面。

一个查询语句的典型结构

QUERY_NAME:{
   ARGUMENT:VALUE,
   ARGUMENT:VALUE,...
}

如果针对于某个字段,那么它的结构如下:

{
  QUERY_NAME:{
     FIELD_NAME:{
       ARGUMENT:VALUE,
       ARGUMENT:VALUE,...
      }   
   }
}
GET bank/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 5,
  "sort": [
    {
      "account_number": {
        "order": "desc"
      }
    }
  ]
}

query定义如何查询;

  • match_all查询类型【代表查询所有的所有】,es中可以在query中组合非常多的查询类型完成复杂查询;
  • 除了query参数之外,我们可也传递其他的参数以改变查询结果,如sort,size;
  • from+size限定,完成分页功能;
  • sort排序,多字段排序,会在前序字段相等时后续字段内部排序,否则以前序为准;
返回部分字段

_source

GET bank/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 5,
  "sort": [
    {
      "account_number": {
        "order": "desc"
      }
    }
  ],
  "_source": ["balance","firstname"]
}
match匹配查询

基本类型(非字符串),精确控制

GET bank/_search
{
  "query": {
    "match": {
      "account_number": "20"
    }
  }
}

字符串,全文检索

// 全文检索 安装评分进行排序 , 会对检索条件进行分词
GET bank/_search
{
  "query": {
    "match": {
      "address": "kings"
    }
  }
}

加上keyword 属性 ,就精确匹配 不进行分词

GET bank/_search
{
  "query": {
    "match": {
      "address.keyword":  "198 Mill Lane"
    }
  }
}
match_phrase [短句匹配]

将需要匹配的值当成一整个单词(不分词)进行检索 , 精确短语匹配

GET bank/_search
{
  "query": {
    "match_phrase": {
      "address": "mill road"
    }
  }
}
multi_math【多字段匹配】

city或者address中包含Mill 或者 Movico,并且在查询过程中,会对于查询条件进行分词。

GET bank/_search
{
  "query": {
    "multi_match": {
      "query": "Mill Movico",
      "fields": ["city","address"]
    }
  }
}
bool用来做复合查询

复合语句可以合并,任何其他查询语句,包括符合语句。这也就意味着,复合语句之间
可以互相嵌套 ,可以表达非常复杂的逻辑。

must:必须达到must所列举的所有条件

must_not,必须不匹配must_not所列举的所有条件。

should,应该满足should所列举的条件。 不满足也行,满足得分更高

GET bank/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {
          "gender": "M"
        }}
      ],
      "must_not": [
        {"match": {
          "age": "32"
        }}
      ],
      "should": [
        {"match": {
          "lastname": "Adams"
        }}
      ]
    }
  }
}
Filter【结果过滤】

并不是所有的查询都需要产生分数,特别是哪些仅用于filtering过滤的文档。为了不计算分数,elasticsearch会自动检查场景并且优化查询的执行。

分词查询 addresss

过滤 age 在18-25之间的

GET bank/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {
          "address": "Road"
        }}
      ],
      "filter": {
        "range": {
          "age": {
            "gte": 18,
            "lte": 25
          }
        }
      }
    }
  }
}

在boolean查询中,must, shouldmust_not 元素都被称为查询子句 。 文档是否符合每个“must”或“should”子句中的标准,决定了文档的“相关性得分”。 得分越高,文档越符合您的搜索条件。 默认情况下,Elasticsearch返回根据这些相关性得分排序的文档。

“must_not”子句中的条件被视为“过滤器”。 它影响文档是否包含在结果中, 但不影响文档的评分方式。 还可以显式地指定任意过滤器来包含或排除基于结构化数据的文档。

must_not 和 filter 区别 : filter 不会计算相关性得分

term

单个字段精确查询 使用term , 多文本分词查询使用match

GET bank/_search
{
  "query": {
    "term": {
      "age": "23"
    }
  }
}
Aggregation(执行聚合)

语法

"aggs":{
    "aggs_name这次聚合的名字,方便展示在结果集中":{
        "AGG_TYPE聚合的类型(avg,term,terms)":{}
     }
}

搜索address中包含mill的所有人的年龄分布以及平均年龄,但不显示这些人的详情

GET bank/_search
{
  "query": {
    "match": {
      "address": "Mill"
    }
  },
  "aggs": {
    "ageAgg": {  //单个聚和取名字
      "terms": {  
        "field": "age",   //操作那一列进行分组
        "size": 10			//显示条数
      }
    },
    "aggs": {
        "ss": {
          "avg": {
            "field": "balance"	//分组结果查询 平均工资
          }
        }
    }"ageAvg": {
      "avg": {
        "field": "age"  //查看所有平均年龄
      }
    },
    "balanceAvg": {  
      "avg": {
        "field": "balance"  //查看所有平均薪资
      }
    }
  },
  "size": 0  //显示0条
}
Mapping
字段类型

示例博客

映射

Mapping(映射)
Maping是用来定义一个文档(document),以及它所包含的属性(field)是如何存储和索引的。比如:使用maping来定义:

  • 哪些字符串属性应该被看做全文本属性(full text fields);

  • 哪些属性包含数字,日期或地理位置;

  • 文档中的所有属性是否都嫩被索引(all 配置);

  • 日期的格式;

  • 自定义映射规则来执行动态添加属性;

查看mapping信息
GET bank/_mapping

//输出
{
  "my_index" : {
    "mappings" : {
      "properties" : {
        "age" : {
          "type" : "integer"
        },
        "email" : {
          "type" : "keyword"
        },
        "employee-id" : {
          "type" : "keyword",
          "index" : false
        },
        "name" : {
          "type" : "text"
        }
      }
    }
  }
}

创建映射

创建索引并指定映射

PUT /my_index
{
  "mappings": {
    "properties": {
      "age": {
        "type": "integer"
      },
      "email": {
        "type": "keyword"
      },
      "name": {
        "type": "text"
      }
    }
  }
}

输出:

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "my_index"
}
  • 如果以存在
{
  "error": {
    "root_cause": [
      {
        "type": "resource_already_exists_exception",
        "reason": "index [my_index/C1GonM4UQ2GEDkPRVubULg] already exists",
        "index_uuid": "C1GonM4UQ2GEDkPRVubULg",
        "index": "my_index"
      }
    ],
    "type": "resource_already_exists_exception",
    "reason": "index [my_index/C1GonM4UQ2GEDkPRVubULg] already exists",
    "index_uuid": "C1GonM4UQ2GEDkPRVubULg",
    "index": "my_index"
  },
  "status": 400
}
添加映射
PUT /my_index/_mapping
{
  "properties": {
    "employee-id": {
      "type": "keyword",
      "index": false    //不是进行索引字段
    }
  }
}
更新映射

对于已经存在的字段映射,我们不能机组更新。更新必须创建新的索引,进行数据迁移。

创建映射
PUT /newbank
{
  "mappings": {
    "properties": {
      "account_number": {
        "type": "long"
      },
      "address": {
        "type": "text"
      },
      "age": {
        "type": "integer"
      },
      "balance": {
        "type": "long"
      },
      "city": {
        "type": "keyword"
      },
      "email": {
        "type": "keyword"
      },
      "employer": {
        "type": "keyword"
      },
      "firstname": {
        "type": "text"
      },
      "gender": {
        "type": "keyword"
      },
      "lastname": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "state": {
        "type": "keyword"
      }
    }
  }
}
数据迁移

将bank中的数据迁移到newbank中

POST _reindex
{
  "source": {
    "index": "bank",
    "type": "account"
  },
  "dest": {
    "index": "newbank"
  }
}
新版本改变

ElasticSearch7-去掉type概念

  1. 关系型数据库中两个数据表示是独立的,即使他们里面有相同名称的列也不影响使用,但ES中不是这样的。elasticsearch是基于Lucene开发的搜索引擎,而ES中不同type下名称相同的filed最终在Lucene中的处理方式是一样的。

    • 两个不同type下的两个user_name,在ES同一个索引下其实被认为是同一个filed,你必须在两个不同的type中定义相同的filed映射。否则,不同type中的相同字段名称就会在处理中出现冲突的情况,导致Lucene处理效率下降。
    • 去掉type就是为了提高ES处理数据的效率。
  2. Elasticsearch 7.x URL中的type参数为可选。比如,索引一个文档不再要求提供文档类型。

  3. Elasticsearch 8.x 不再支持URL中的type参数。

  4. 解决:
    将索引从多类型迁移到单类型,每种类型文档一个独立索引

    将已存在的索引下的类型数据,全部迁移到指定位置即可。详见数据迁移

ik 分词器

安装

下载与es对应版本

https://github.com/medcl/elasticsearch-analysis-ik/releases

把ik 解压到 文件夹 /mydata/elasticsearch/plugins/ 下

设置权限

chmod -R 777 ik/

配置nginx使用ik

  • 随便启动一个nginx实例,只是为了复制出配置

    docker run -p80:80 --name nginx -d nginx:1.10   
    
  • 将容器内的配置文件拷贝到/mydata/nginx/conf/ 下

    mkdir -p /mydata/nginx/html
    mkdir -p /mydata/nginx/logs
    mkdir -p /mydata/nginx/conf
    docker container cp nginx:/etc/nginx/*  /mydata/nginx/conf/ 
    #由于拷贝完成后会在config中存在一个nginx文件夹,所以需要将它的内容移动到conf中
    mv /mydata/nginx/conf/nginx/* /mydata/nginx/conf/
    rm -rf /mydata/nginx/conf/nginx
    
  • 终止原容器:

    docker stop nginx
    
  • 执行命令删除原容器:

    docker rm nginx
    
  • 创建新的Nginx,执行以下命令

    docker run -p 80:80 --name nginx \
    -v /mydata/nginx/html:/usr/share/nginx/html \
    -v /mydata/nginx/logs:/var/log/nginx \
    -v /mydata/nginx/conf/:/etc/nginx \
    -d nginx:1.10
    
  • 设置开机启动nginx

    docker update nginx --restart=always
    
  • 创建“/mydata/nginx/html/index.html”文件,测试是否能够正常访问

    echo '<h2>hello nginx!</h2>' >index.html
    

    访问:http://ngix所在主机的IP:80/index.html

配置分词

vi /mydata/elasticsearch/plugins/ik/config/IKAnalyzer.cfg.xml

在添加分词

html/es/fenci.txt

重启es测试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明明吃了饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值