简介:
ElasticSearch是一个分布式,RESTful风格的搜索和数据分析引擎
官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
一、基本概念
1、index(索引)
动词:相当于MySql的insert
名词:相当于MySql的database
2、Type (类型)
在index中,可以定义一个或多个类型
类似于mysql的table,每种类型的数据放在一起
3、Document(文档)
保存在某个索引(index)下,某种类型(Type)的一个数据(Document),文档是json形式的,
Documnet类似于table中的一行
4、倒排索引机制
es会维持一个倒排索引,当其存入一个数据时,会对该数据中的内容进行分词,然后该词语后
维持一个该文档的id
二、ElasticSearch - Docker安装
1、下载镜像文件
docker pull elasticsearch:7.4.2 docker pull kibana:7.4.2
2、创建实例
创建文件夹和配置文件
mkdir -p /mydata/elasticsearch/config mkdir -p /mydata/elasticsearch/data echo "http.host : 0.0.0.0" >> /mydata/elasticsearch/config/elasticsearch.yml
创建容器
9200: restful请求的端口 9300:elasticsearch集群节点间通信端口 discovery.type=single-node 以单节点形式运行 ES_JAVA_OPTS 设置es运行的java虚拟机内存 -v :目录挂载 -d : 以守护进程方式运行
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \ -e "discovery.type=single-node" \ -e ES_JAVA_OPTS="-Xms64m -Xmx128m" \ -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
【注意】:启动错误时,需要改一下 数据目录的权限 /mydata/elasticsearch/data
chmod 777 /mydata/elasticsearch/data
访问 elasticsearch服务所在机器的 9200端口
http://192.168.25.129:9200/
3、【补充】 docker 安装kibana
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.25.129:9200 -p 5601:5601 \ -d kibana:7.4.2
访问kibana服务所在机器的5601端口
http://192.168.25.129:5601/
三、初步检索
1、_cat
GET /_cat/nodes : 查看所有结点
GET /_cat/health : 查看es的健康状况
GET /_cat/master : 查看主节点
GET /_cat/indices :查看所有索引
2、索引一个文档
保存一个数据,保存在哪个索引的哪个类型下,指定用哪个唯一标识
PUT customer/external/1 : 在customer索引下的 external 类型下保存1号数据
PUT customer/external/1 { "name":"houchen" }
返回数据:
{ "_index" : "customer", // 带_的为元数据 索引 "_type" : "external", "_id" : "1", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 0, "_primary_term" : 1 }
【总结】
PUT 和 POST都可以进行新增操作
PUT必须要带id,id存在的话即修改,id不存在的话则是新增
带id的情况下,多次PUT/POST是修改
不带id的情况下,多次POST是新增
3、查询文档
GET /customer/external/1
结果: { "_index" : "customer", //在哪个索引 "_type" : "external", //在哪个类型 "_id" : "1", //记录id "_version" : 1, //版本号 "_seq_no" : 0, //并发控制字段,每次更新就会+1,用来做乐观锁 "_primary_term" : 1, //同上,主分片重新分配,会重启就会变化 "found" : true, //是否找到 "_source" : { "name" : "houchen" } }
并发修改时,需要携带 _seq_no
4、更新文档
带 _update的更新语句:会对比原来的数据,如果没有变化,则版本号不会更新
POST customer/external/1/_update { "doc":{ "name":"john Doew" } }
不带_update的更新语句,会不断更新,叠加版本_version
POST customer/external/1 { "name":"john Doew" } PUT customer/external/1 { "name":"john Doew" }
5、删除文档和索引
删除文档
DELETE customer/external/1
删除索引
DELETE customer
6、bulk批量API
POST /customer/external/_bulk {"index":{"_id":"1"}} {"name":"111"} {"index":{"_id":"2"}} {"name":"222"}
复杂操作:
POST /_bulk {"delete":{"_index":"wehsite","_type":"blog","_id":"123"}} //删除文档 {"create":{"_index":"wehsite","_type":"blog","_id":"123"}} //创建文档 {"title":"My first blog post"} {"index":{"_index":"wehsite","_type":"blog"}} //索引文档 {"title":"My second blog post"} {"update":{"_index":"wehsite","_type":"blog","_id":"123"}} {"doc":{"title":"My second blog post"}}
【导入官网测试数据】
post /bank/account/_bulk { {"index":{"_id":"1"}} {"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"} {"index":{"_id":"6"}} {"account_number":6,"balance":5686,"firstname":"Hattie","lastname":"Bond","age":36,"gender":"M","address":"671 Bristol Street","employer":"Netagy","email":"hattiebond@netagy.com","city":"Dante","state":"TN"} {"index":{"_id":"13"}} }
https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip
四、进阶检索
ES支持两种基本方式检索:
一个是通过使用 REST request URI来发送搜索参数(uri + 检索参数)
GET bank/_search?q=*&sort=account_number:asc
另一个是通过 REST request body 来发送他们 (uri + 请求体)
GET bank/_search { "query":{ "match_all":{} }, "sort":[ { "balance":{ "order":"desc" } } ], "from":0, "size":5, "_source":["balance","firstname"] }
1、match_all :查询所有
GET bank/_search { "query":{ "match_all":{} }, "sort":[ { "balance":"asc" } ] }
2、match查询
全文检索会按照评分进行排序,
首选需要对要查询的字符串进行分词,然后根据分词的结果进行匹配
最后根据得分进行排序
GET bank/_search { "query": { "match": { "address": "kings" } } }
3、match_phrase 【短语匹配】
将需要匹配的值,当成一个整体单词(不分词)进行检索
GET bank/_search { "query": { "match_phrase": { "address": "mill lane" } } }
4、multi_match 【多字段匹配】
也是分词查询
// 查询 adress或者city中包含 mill的数据 GET bank/_search { "query": { "multi_match": { "query": "mill", "fields": ["address","city"] } } }
5 bool查询
GET bank/_search { "query": { "bool": { "must":[ { "match": { "gender": "F" } }, { "match": { "address": "Mill" } } ] } } }
6、filter 结果过滤
只用于对数据进行过滤,不会计算相关性得分
GET bank/_search { "query": { "bool": { "filter": { "range": { "age": { "gte": 10, "lte": 20 } } } } } }
7、term 查询
和match一样。匹配某个属性的值。全文检索用match,其他非text字段匹配用term
GET /bank/_search { "query": { "term": { "balance": { "value": "32838" } } } }
精确匹配:查询address等于132 Gunnison的文档
GET bank/_search { "query": { "match": { "address.keyword": "132 Gunnison" } } }
8、aggregation (执行聚合)
聚合提供了从数据中分组和提取数据的能力。最简单的聚合大致等于SQL的聚合函数。
在ElasticSearch中,你有执行搜索返回hit,并且同时返回聚合结果,把一个响应中所有hits分隔开的
能力,这是非常强大且有效的。您可以执行查询和多个聚合并且在一次使用中得到各自的返回结果,使用一次简介和简化的api来避免网络往返
语法
"aggregations" : { "<aggregation_name>" : { //聚合名称 "<aggregation_type>" : { //聚合类型 <aggregation_body> //聚合体 } [,"meta" : { [<meta_data_body>] } ]? [,"aggregations" : { [<sub_aggregation>]+ } ]? } [,"<aggregation_name_2>" : { ... } ]* }
1)需求:搜索address中包含mail的所有人的年龄和平均年龄,但不显示这些人的详情
GET bank/_search { "query": { "match": { "address": "mill" } }, "aggs": { "ageagg": { "terms": { "field": "age", "size": 10 } }, "ageavg":{ "avg": { "field": "age" } }, "balanceavg":{ "avg": { "field": "balance" } } } }
2)按照年龄聚合,并求这些年龄段的人的平均薪资
(聚合里面套聚合)
GET /bank/_search { "query":{ "match_all": {} }, "aggs": { "ageAgg": { "terms": { "field": "age", "size": 10 }, "aggs": { "balanceAvg": { "avg": { "field": "balance" } } } } }, "size": 0 ##过滤掉查询的结果 }
3)查出所有的年龄分布,并且这些年龄段中M的平均薪资和F的平均薪资,以及这个年龄段总体的平均薪资
GET bank/_search { "query": { "match_all": {} }, "aggs": { "agegg": { //聚合年龄 "terms": { "field": "age", "size": 100 }, "aggs": { "genderagg":{ //在年龄的聚合结果上聚合性别 "terms": { "field": "gender.keyword", "size": 2 }, "aggs": { "balanceagg": { //xx岁 M性别的平均薪资 "avg": { "field": "balance" } } } }, "agebalanceaavg":{ //xx岁的平均薪资 "avg": { "field": "balance" } } } } } }