elasticsearch的安装与基础入门
使用docker启动单节点集群
docker pull docker.elastic.co/elasticsearch/elasticsearch:8.1.2
docker network create elastic
docker run --name es01 --net elastic -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -it docker.elastic.co/elasticsearch/elasticsearch:8.1.2
默认使用ssl,修改配置文件禁用ssl,启动容器服务,进入目录:/usr/share/elasticsearch/config
修改配置文件elasticsearch.yml,修改下面一行true-->false,重启服务
xpack.security.enabled: false
配置中文分词器ik
-
下载Ik分词器,下载链接见官网
官网 IK8.1.2下载链接 -
将下载文件解压
unzip elasticsearch-analysis-ik-8.1.2.zip
-
在 es/plugins 目录下,新建 ik 目录,并将解压后的所有文件拷贝到 ik 目录下。
-
重启es服务
基本概念
-
index
查看当前节点的所有Index
curl http://ip:9200/_cat/indices?v
?v的意思是打印标题 -
document
index里面的单条记录称为document,许多document构成了一个index,document使用Json格式表示,
同一个Index里面的document不要求有相同的结构(schema),但是最好相同,这样有利于提高搜索效率 -
type
document可以分组,比如weather这index里面,可以按城市分组,也可以按气候分组,不同type应该有相同的结构(schema)
比如说Id字段不能在这个组是字符串,在另外一个组是是数值
列出每个index下所包含的type
curl http://ip:9200/_mapping?pretty=true
- 根据规划,Elastic 6.x 版只允许每个 Index 包含一个 Type,7.x 版将会彻底移除 Type。
新建和删除index
-
新建index
curl -X PUT ip:9200/weather
-
删除index
deletehttp://ip:9200/weather
数据操作
- 向指定Index添加一条记录
put/posthttp://ip:9200/accounts/_doc/1
body:
{
"user": "张三",
"title": "工程师",
"desc": "数据库管理"
}
- 注意:如果没有先创建Index(这个例子是accounts),直接执行上面的命令,es也不会报错,而是直接生成指定的Index
- 查看一条记录
gethttp://ip:9200/accounts/_doc/1
{
"_index": "accounts",
"_id": "1",
"_version": 2,
"_seq_no": 1,
"_primary_term": 1,
"found": true,
"_source": {
"user": "张三",
"title": "工程师",
"desc": "数据库管理"
}
}
返回的数据中,found字段表示查找成功,_course字段返回原始记录
如果id不正确,就是查找不到数据found返回false
-
删除记录
deletehttp://ip:9200/accounts/_doc/1
删除成功result返回:deleted, 删除失败result返回:not_found -
更新记录
puthttp://ip:9200/accounts/_doc/1
更新记录就是使用put请求重新发送一次数据,可以看到记录id没变,版本_version发生了变化
result返回的是updated
数据查询
- 返回所有记录
get http://mayanan.cn:9200/accounts/_search
返回accounts索引下的所有记录
点击查看代码
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "accounts",
"_id": "1",
"_score": 1.0,
"_source": {
"user": "张三",
"title": "工程师",
"desc": "数据库管理,软件开发"
}
}
]
}
}
took字段表示该操作的耗时,单位毫秒,time_out字段表示是否超时,hits字段表示命中的记录,hits里面字段的含义如下
total: 返回记录数
max_score: 最高的匹配程度,本例是1.0
hits: 返回的记录组成的数组
返回的记录中,每条记录都有一个_score字段,表示匹配程度,默认是按照这个字段降序排列
- 全文搜索
es的查询非常特别,使用自己的查询语法,
要求get请求带有数据体
{
"query": {"match": {"desc": "管理"}}
}
上面的代码是使用match查询,指定的匹配条件是desc字段里面的“软件”这个词
- es默认返回10条结果,可以通过size设置返回的结果数量
{
"query": {"match": {"desc": "管理"}},
"size": 1
}
上面代码,每次只返回一条结果
可以通过from字段,指定位移
{
"query": {"match": {"desc": "管理"}},
"size": 1,
"from": 1
}
上面代码,从位置1开始(默认是从位置0开始),只返回一条结果
- 逻辑运算
如果有多个搜索关键字,es认为它们是or关系
{
"query": {"match": {"desc": "软件 系统"}}
}
上面代码搜索的是软件or系统
如果要执行多个关键词的and搜索,必须使用布尔查询
{
"query": {
"bool": {
"must": [
{"match": {"desc": "软件"}},
{"match": {"desc": "系统"}}
]
}
}
}
- 查询一共有多少个文档
查询索引下有多少个文档
get http://ip:9200/accounts/_count
查询集群下有多少个文档
get http://ip:9200/_count
请求参数
{
"query": {
"match_all": {}
}
}
- 在es中,将对象转化为json构建索引要比要比一个扁平的表结构中构建容易的多
- 全字段搜索
{
"query":{
"multi_match":{
"query": "工程师"
}
}
}
- 还可以指定字段搜索
{
"query":{
"multi_match":{
"query": "工程师",
"fields": ["user", "desc", "title"]
}
}
}
- http://ip:9200/megacorp/_doc/1
get获取文档、put更新/添加文档、post添加/更新文档、delete删除文档
先构建数据,索引员工文档
post /megacorp/_doc/1
post /megacorp/_doc/2
post /megacorp/_doc/3
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
{
"first_name" : "Jane",
"last_name" : "Smith",
"age" : 32,
"about" : "I like to collect rock albums",
"interests": [ "music" ]
}
{
"first_name" : "Douglas",
"last_name" : "Fir",
"age" : 35,
"about": "I like to build cabinets",
"interests": [ "forestry" ]
}
-
搜索指定索引下的所有文档
get /megacorp/_search -
通过查询字符串搜索文档
get /megacorp/_search?q=last_name:Smith -
使用DSL查询
get /megacorp/_search
{
"query":{
"match":{
"last_name":"smith"
}
}
}
- 按照所有字段检索
get /megacorp/_search
{
"query":{
"multi_match":{
"query": "Smith"
}
}
}
- 同样搜索姓氏为 Smith 的员工,但这次我们只需要年龄大于 30 的。
使用filter过滤器,它支持高效的执行一个结构化查询
{
"query": {
"bool": {
"must": {
"match": {"last_name": "SMITH"}
},
"filter": {
"range": {
"age": {"gt": 30}
}
}
}
}
}
- 全文搜索
尝试一下高级点的全文搜索,一项传统数据库很难搞定的任务
{
"query": {
"match": {
"about": "rock limbing"
}
}
}
es按照相关性得分排序,即每个文档跟查询的匹配程度,该案例说明了es如何在全文属性上搜索
并返回相关性最强的结果,es中相关性概念非常重要,也是完全区别于传统数据库的一个概念
数据库中的一条记录要么匹配,要么不匹配
- 短语搜索
找出一个属性中的独立单词是没有问题的,但有时候想要精确匹配一系列单词或者_短语_ 。 比如, 我们想执行这样一个查询,仅匹配同时包含 “rock” 和 “climbing” ,并且 二者以短语 “rock climbing” 的形式紧挨着的雇员记录。
get /megacorp/_search
{
"query": {
"match_phrase": {
"about": "rock climbing"
}
}
}
- 高亮搜索
get /megacorp/_search
{
"query": {
"match_phrase": {
"about": "rock climbing"
}
},
"highlight": {
"fields": {
"about": {}
}
}
}
- 分析
es有一个功能叫做聚合,聚合与sql中的group by很相似,但功能更强大
get /megacorp/_search
{
"aggs": {
"all_interests": {
"terms": { "field": "interests.keyword" }
}
}
}
可以看到,两位员工对音乐感兴趣,一位对林业感兴趣,一位对运动感兴趣。这些聚合的结果数据并非预先统计,而是根据匹配当前查询的文档即时生成的。
如果想知道Smith员工最受欢迎的兴趣爱好,直接构造一个组合查询
get /megacorp/_search
{
"query": {
"match": {
"last_name": "Smith"
}
},
"aggs": {
"all_interests": {
"terms": { "field": "interests.keyword" }
}
}
}
聚合还支持分级汇总,比如查询特定兴趣爱好员工的平均年龄
get /megacorp/_search
{
"aggs": {
"all_interests": {
"terms": { "field": "interests.keyword" },
"aggs": {
"avg_age": {
"avg": {"field": "age"}
}
}
}
}
}
输出是第一次聚合的加强版,依然有一个兴趣及数量的列表,只不过每个兴趣都有了一个附件加avg_age属性,
代表有这个兴趣爱好的所有员工的平均年龄,
-
教程结语
欣喜的是,这是一个关于 Elasticsearch 基础描述的教程,且仅仅是浅尝辄止,更多诸如 suggestions、geolocation、percolation、fuzzy 与 partial matching 等特性均被省略,以便保持教程的简洁。但它确实突显了开始构建高级搜索功能多么容易。不需要配置——只需要添加数据并开始搜索! -
分布式特性
在本章开头,我们提到过 Elasticsearch 可以横向扩展至数百(甚至数千)的服务器节点,同时可以处理PB级数据。我们的教程给出了一些使用 Elasticsearch 的示例,但并不涉及任何内部机制。Elasticsearch 天生就是分布式的,并且在设计时屏蔽了分布式的复杂性。
Elasticsearch 在分布式方面几乎是透明的。教程中并不要求了解分布式系统、分片、集群发现或其他的各种分布式概念。可以使用笔记本上的单节点轻松地运行教程里的程序,但如果你想要在 100 个节点的集群上运行程序,一切依然顺畅。
Elasticsearch 尽可能地屏蔽了分布式系统的复杂性。这里列举了一些在后台自动执行的操作:
分配文档到不同的容器 或 分片 中,文档可以储存在一个或多个节点中
按集群节点来均衡分配这些分片,从而对索引和搜索过程进行负载均衡
复制每个分片以支持数据冗余,从而防止硬件故障导致的数据丢失
将集群中任一节点的请求路由到存有相关数据的节点
集群扩容时无缝整合新节点,重新分配分片以便从离群节点恢复
当阅读本书时,将会遇到有关 Elasticsearch 分布式特性的补充章节。这些章节将介绍有关集群扩容、故障转移(集群内的原理) 、应对文档存储(分布式文档存储) 、执行分布式搜索(执行分布式检索) ,以及分区(shard)及其工作原理(分片内部原理) 。
- 后续步骤
现在大家对于通过 Elasticsearch 能够实现什么样的功能、以及上手的难易程度应该已经有了初步概念。Elasticsearch 力图通过最少的知识和配置做到开箱即用。学习 Elasticsearch 的最好方式是投入实践:尽情开始索引和搜索吧!
然而,对于 Elasticsearch 知道得越多,就越有生产效率。告诉 Elasticsearch 越多的领域知识,就越容易进行结果调优。
本书的后续内容将帮助你从新手成长为专家,每个章节不仅阐述必要的基础知识,而且包含专家建议。如果刚刚上手,这些建议可能无法立竿见影;但 Elasticsearch 有着合理的默认设置,在无需干预的情况下通常都能工作得很好。当你开始追求毫秒级的性能提升时,随时可以重温这些章节。