最新ElasticSearch7.9 中文教程
发布者:admin发表于:813天前阅读数:2327评论:0
关键词:数据库

ES 与SOLR

1.Solr在查询固定数据时,速度相对ES更快一些,但是数据如果是实时改变的,Solr的查询速度会降低很多,Es的查询的效率基本没有变化

2.Solr搭建基于需要依赖 Zookeeper来帮助管理,ES本身就支持集群的搭建,不需要第三方的介入

3.最开始Solr的社区可以说是非常火爆,针对国内的文档井不是很多,在ES出现之后,ES的社区火爆程度, 直线上升,Es的文档非常健全

4.ES对现在云计算和大数据支持的特别好

倒排序

将存放的数据,以一定的方式进行分词,并且将分词的内容存放到一个单独的分词库中

当用户去查询数据时,会将用户的查询关键字进行分词

然后去分词库中匹配内容,最终得到数据的d标识

根据d标识去存放数据的位置拉取到指定的数据

安装

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.6.2-linux-x86_64.tar.gz #下载tar -zxvf elasticsearch-7.6.2-linux-x86_64.tar.gz #解压cd elasticsearch-7.6.2bin/elasticsearch

配置

elasticsearch.yml

配置项备注
node.name节点名称 打开
network.host监听ip,打开 0.0.0.0
discovery.seed_hosts初始服务器ip “127.0.0.1”
cluster.initial_master_nodes主节点 打开
cluster.name集群组名称

jvm.options

项目说明
-Xms256m初始内存大小
-Xmx256m最大内存大小

报错解决

  1. 错误:Exception in thread “main” java.lang.RuntimeException: don’t run elasticsearch as root.

原因:我们在使用elasticsearch的时候,如果是以root权限来执行elasticsearch则会报错,这是出于系统安全考虑设置的条件。由于ElasticSearch可以接收用户输入的脚本并且执行,为了系统安全考虑,
建议创建一个单独的用户用来运行ElasticSearch

解决:

groupadd elsearch #创建elsearch用户组及elsearch用户useradd elsearch -g elsearch -p elasticsearch #创建elsearch用户chown -R elsearch:elsearch elasticsearch-7.6.2 #更改elasticsearch文件夹及内部文件的所属用户及组为elsearch:elsearchsu elsearch #切换账户cd elasticsearch-7.6.2/bin #进入你的elasticsearch目录下的bin目录./elasticsearch -d #启动ps aux|grep elasticsearch #查看是否正常运行
  1. 错误:max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

原因:elasticsearch用户拥有的内存权限太小,至少需要262144;

解决:切换到root用户,执行命令:

sysctl -w vm.max_map_count=262144 #查看结果:sysctl -a|grep vm.max_map_count #显示:vm.max_map_count = 262144 #上述方法修改之后,如果重启虚拟机将失效,所以:解决办法:在 /etc/sysctl.conf文件最后添加一行vm.max_map_count=262144即可永久修改

ES与mysql对应关系

mysqlES
数据库Index
type (6以后已经作废)
一行记录Document
Field
Schema约束mapping
索引
SQL语句Query DSL
Select * from tableGET http://…
update table set …PUT http://…

Mapping映射

创建索引时预定义字段类型和相关属性,让索引更完善,提高查询效率

ES常用字段类型

常用类型ES中type类型备注
string,varchar,texttext
keyword
5.x以后不再支持string
text类型:当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型。设置text类型以后,字段内容会被分析,在生成倒排索引以前,字符串会被分析器分成一个一个词项。text类型的字段不用于排序,很少用于聚合。
keyword类型适用于索引结构化的字段,比如email地址、主机名、状态码和标签。如果字段需要进行过滤(比如查找已发布博客中status属性为published的文章)、排序、聚合。keyword类型的字段只能通过精确值搜索到。
integerbyte
short
integer
long
float,doublefloat
double
half_float
scaled_float
32位单精度IEEE 754浮点类型
64位双精度IEEE 754浮点类型
16位半精度IEEE 754浮点类型
缩放类型的的浮点数
booleanbooleantrue和false
date/datetimedate1. 日期格式的字符串,比如 “2018-01-13” 或 “2018-01-13 12:10:30”
2. long类型的毫秒数( milliseconds-since-the-epoch,epoch就是指UNIX诞生的UTC时间1970年1月1日0时0分0秒)
3. integer的秒数(seconds-since-the-epoch)
bytes/binarybinary进制字段是指用base64来表示索引中存储的二进制数据,可用来存储二进制形式的数据,例如图像。默认情况下,该类型的字段只存储不索引。二进制类型只支持index_name属性。
arrayarray1. 字符数组: [ “one”, “two” ]
2. 整数数组: productid:[ 1, 2 ]
3. 对象(文档)数组: “user”:[ { “name”: “Mary”, “age”: 12 }, { “name”: “John”, “age”: 10 }],
注意:elasticSearch不支持元素为多个数据类型:[ 10, “some string” ]
objectJSON对象,文档会包含嵌套的对象
ipip类型的字段用于存储IPv4或者IPv6的地址

Mapping 支持属性

属性描述适用字段类型
store是否单独设置此字段的是否存储而从_source字段中分离,只能搜索,不能获取值
“store”: false(默认)true
all
index是否构建倒排索引(即是否分词,设置false,字段将不会被索引)
“index”: true(缺省)false
string
null_value设置一些缺失字段的初始化,只有string可以使用,分词字段的null值也会被分词
“null_value”: “NULL”
string
boost检索时,字段级优先权重,默认值是1.0
“boost”: 1.23
all
search_analyzer设置搜索时的分词器,默认跟analyzer是一致的,比如index时用standard+ngram,搜索时用standard用来完成自动提示功能
“search_analyzer”: “ik”
text
analyzer指定分词器,默认分词器为standard analyzer
“analyzer”: “ik”
text
include_in_allall
index_nameall
norms是否归一化相关参数、如果字段仅用于过滤和聚合分析、可关闭
分词字段默认配置,不分词字段:默认{“enable”: false},存储长度因子和索引时boost,建议对需要参加评分字段使用,会额外增加内存消耗
“norms”: {“enable”: true, “loading”: “lazy”}
all

更多参考https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-params.html

PUT /store { "mappings":{ "properties":{ "title":{ "type":"keyword" }, "price":{ "type":"integer" } } }}

中文分词

下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases

安装插件:把插件包 elasticsearch-analysis-ik(需要mvn编译过)解压到 elasticsearch\plugins\ik目录下,后启动ES 自动识别

测试分词

POST _analyze{ "analyzer": "ik_smart", "text": "我是一个程序员"}

创建mapping 分词只能用于text类型

PUT /store { "mappings":{ "properties":{ "title":{ "type":"text", "analyzer":"ik_max_word", "search_analyzer":"ik_max_word" }, "price":{ "type":"integer" } } }}

使用方法

访问方式

http://ip:9200/index/type/[id] #api格式curl -H "ContentType:application/json" -X PUT 127.0.0.1:9200/index -d '{ "settings":{ "number_of_shards":1, "number_of_replicas":0 }}'#命令行格式PUT /index{ "settings":{ "number_of_shards":1, "number_of_replicas":0 }}

查看健康状态

curl -X GET 127.0.0.1:9200/_cat/health?v

查询当前es集群中所有的indices

curl -X GET 127.0.0.1:9200/_cat/indices?v

创建初始化索引

PUT /store { "settings":{ "number_of_shards":1, //分片数量 "number_of_replicas":0 //备份数量 }, "mappings":{ "properties":{ "title":{ "type":"text", "analyzer":"ik_max_word" }, "price":{ "type":"integer" } } }}#blocks.read_only:true //只读#blocks.read:true //禁止读#blocks.write:true //禁止写#blocks.metadata:true //禁止操作metadata

向已有索引中添加新字段

POST /store/_mappings{ "properties":{ "status":{ "type":"integer" } } }

不支持删除或更新某个字段

获取索引配置

GET /store/_settings //获取配置GET /index1,index2/_settings //获取2个索引配置GET /_all/_settings //获取所有配置

删除记录

DELETE /store 索引DELETE /index/_doc/id 记录

删除条件记录

据term, match等查询方式去删除大量的文档 GET /store/_search替换成POST /store/_doc/_delete_by_query

Ps:如果需要删除的内容,是index下的大部分数据,推荐创建一个全新的index,将保留的文档内容,添加到全新的索引

POST /store/_doc/_delete_by_query{ query:条件}

插入记录

使用POST时不指定id, 会自动生成uuid,不方便更新删除,不推荐

POST /store/_doc{ "title": "php", "price": 20, "create_time": "2016-06-06"}

也可以使用PUT方法,但是需要传入id

PUT /store/_doc/4 { "title": "php", "price": 20, "create_time": "2016-06-06"}

获取记录

GET /store/_doc/idGET /store/_doc/id?_source=title //查询指定字段

更新记录指定字段

POST /store/_update/id{ "doc":{ "price":10 }}或PUT /store/_doc/id{ "price":50}

更新覆盖整条记录

POST /store/_doc/id{ "title": "php", "price": 20, "create_time": "2016-06-06"}

批量获取

GET /_mget{ "docs":[ { "_index" : "store", "_type" : "book", "_id" : 3 "_source":"price" //可指定字段,多个用数组形式 [] }, { "_index" : "store", "_type" : "book", "_id" : 4 } ]}//获取同一个索引同一个type下不同idGET /store/_mget{ "ids":["3","4"]}

Bulk批量CURD

行为备注
create文档不存在时创建
index创建新文档或替换已有文档
update局部更新
delete删除文档
{action:{metadata}}\n{requestbody}\n

批量新增加

POST /store/_bulk{"index":{"_id":1}}{"title":"php是世界上最好的语言","price":30}{"index":{"_id":2}}{"title":"java是世界上最难的语言","price":20}{"index":{"_id":3}}{"title":"python是人工智能语言","price":35}

批量删除

POST /store/_bulk{"delete":{"_id":1}}

批量更新

POST /store/_bulk{"update":{"_id":2}}{"doc":{"price":12}}

版本控制

版本控制用于乐观锁,内部版本控制:(version已被7淘汰,7使用if_seq_no 和 if_primary_term)

PUT /store/_doc/1?if_seq_no=0&if_primary_term=1{ "price":50}

版本控制用于乐观锁,外部版本控制,更新时外部版本号不得小于内部版本号:

PUT /store/_doc/1?version=4&version_type=external{ "price":50}

检索查询

Elasticsearch的检索语法比较特别,使用GET方法携带JSON格式的查询条件。

全检索:

curl -X GET 127.0.0.1:9200/store/_doc/_search

按条件检索:

_search: 查询

query:查询条件

​ bool:聚合查询组合条件 相当于()

​ must:必须满足 相当于and =

​ should:条件可以满足 相当于or

​ must_not:条件不需要满足,相当于and not

​ range:范围

​ gt: 大于

​ lt:小于

​ gte:大等于

​ lte:小等于

​ filter:条件过滤

​ term:不分词

普通查询

分页查询相当于limit

from和size 之合不能超过10000

GET /store/_search{ "from":0, "size":10}

使用term查询

term查询不会对指定关键词进行分词,而是从分词库中匹配

相当于 where title =”java”

GET /store/_search{ "query":{ "term":{ "title":"java" } }}

使用terms查询查询多个值

相当于 where title in (“php”,”java”)

GET /store/_search{ "query":{ "terms": { "title":["php","java"] } } }

match高级查询

match查询属于高层查询,他会根据你查询的字段类型不一样,采用不同的查询方式。

  • 查询的是日期或者是数值的话,他会将你基于的字符串查询内容转换为日期或者数值对待。

  • 如果查询的内容是一个不能被分词的内容( keyword), match查询不会对你指定的查询关键字进行分词

  • 如果查询的内容时一个可以被分词的内容(text), match会将你指定的查询内容根据一定的方式去分词,去分词库中匹配指定的内容。

match查询,实际底层就是多个term查询,将多个term查询的结果给你封装到了一起

默认查询10条记录

GET /store/_search{ "query":{ "match": { "title":"php" } } }

match_all查询,返回所有数据,不指定查询条件

GET /store/_search{ "query":{ "match_all": {} } }

match_phrase查询,短语查询,slop定义关键词之间间隔多少未知单词 用逗号或空格间隔多个关键词

GET /store/_search{ "query":{ "match_phrase": { "title":{ "query":"p,p", "slop":2 } } } }

布尔match 基于一个字段,采用and或or的条件查询 用逗号或空格间隔多个关键词

GET /store/_search{ "query":{ "match": { "title":{ "query":"php java python", "operator":"or" } } } }

multi_match查询基于多个字段查询一个关键词

GET /store/_search{ "query":{ "multi_match": { "query":"php", "fields":["title"] } } }

其他查询

查询效率较低

perfix 前缀查询

类似 like “key%”

GET /store/_search{ "query":{ "prefix": { "title":"php" } } }

fuzzy相似查询

具有容错性

GET /store/_search{ "query":{ "fuzzy": { "title":{ "value":"php", "prefix_length":3 //可选,前三个不允许错 } } } }

wildcard查询

通配符 ? 或 *,?占一个字符

GET /store/_search{ "query":{ "wildcard": { "title":{ "value":"p??" } } } }

range查询

范围查询只针对数值 where (price>=20 and price <30) 符号 gt,gte,lt,lte

GET /store/_search{ "query":{ "range": { "price":{ "gte":20, "lt":30 } } } }

regexp正则查询

GET /store/_search{ "query":{ "regexp": { "title":"[a-p]h.*?" } } }

深分页scroll

ES对from+size是有限制的,from和size二者之和不能超过1W

from+size ES查询数据的方式:

  • 第一步现将用户指定的关键进行分词
  • 第二步将词汇去分词库中进行检索,得到多个文档的id
  • 第三步去各个分片中去拉取指定的数据,耗时较长
  • 第四步将数据根据 score进行排序
  • 第五步根据from的值,将查询到的数据舍弃一部分
  • 第六步返回结果

scroll查询数据方式

  • 第一步现将用户指定的关键进行分词

  • 第二步将词汇去分词库中进行检索,得到多个文档的id

  • 第三步将文档的d存放在一个Es的上下文中

  • 第四步根据你指定的size的个数去Es中检索指定个数的数据,拿完数据的文档id,会从上下文中移

  • 第五步如果需要下一页数据,直接去ES的上下文中,找后续内容

Scroll查询方式,不适合做实时的查询

GET /store/_search?scroll=1m{ "query":{ "match_all": { } }, "size":2, "sort":[{ "price":{ "order":"desc" } }]}

查询结果中的 scroll_id 是内存上下文id, 用id查询下一页

GET /_search/scroll{ "scroll_id":"", "scroll":"1m"}

删除scroll

DELETE /_search/scroll/FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFERCUjRxM1VCS3gxSGNZVURIWWRJAAAAAAAAC5sWUmprMWhGYUpSNUd2X25paTg2RVROdw==

组合查询

bool查询

复合过滤器,将你的多个查询条件,以一定的逻辑组合在一起

must:所有的条件,用mus组合在一起,表示and true的意思

must not:将 must not中的条件,全部都不能匹配,标识and not true的意思

should:所有的条件,用 should组合在一起,表示or true的意思

例如 select * from store where (price=20 or price =30) and create_time <>”2016-06-06”

{ "query":{ "bool": { "should":[ {"term":{"price":20}}, {"term":{"price":30}} ], "must_not":{ "term":{"create_time":"2016-06-06"} } }, } }

boosting 查询

boosting查询可以帮助我们去影响查询后的 score

  • positive:只有匹配上 positive的意询的内容,才会被放到返回的结果集中
  • negative:如果匹配上和 positive并且也匹配上了 negative,就可以降低这样的文档 score
  • negative boost:指定系数,必须小于1.0 系数会乘上score 降低排名

关于查询时,分数是如何计算的

  • 搜索的关键字在文档中出现的频次越高,分数就越高
  • 指定的文档内容越短,分数就越高
  • 我们在搜索时,指定的关键字也会被分词,这个被分词的内容,被分词库匹配的个数越多,分数越高
GET /store/_search{ "query":{ "boosting":{ "positive":{ "match": { "title": "java" } }, "negative": { "match": { "title": "y" } }, "negative_boost": 0.2 } }}

filter查询

query,根据你的查询条件,去计算文档的匹配度得到一个分数,并且根据分数进行排序,不会做缓存的

filter,根据你的查询条件去查询文档,不去计算分数,而且filter会对经常被过滤的数据进行缓存

GET /store/_search{ "query":{ "bool":{ "filter":[ { "term":{ "title":"java" } }, { "term":{ "price":20 } } ] } }}

高亮查询

高亮查询就是你用户输入的关键字,以一定的特殊样式展示给用户,让用户知道为什么这个结果被检索出来

高亮展示的数据,本身就是文档中的一个Feld,单独将 FieldlAhighlight的形式返回给你

ES提供了一个 highlight属性,和 query同级别的

  • fields:指定哪些字段按高亮返回

  • fragment_size:指定高亮数据展示多少个字符回来

  • pre_tags:指定前缀标签
  • post_tags:指定后缀标签
GET /store/_search{ "query":{ "term":{ "title":"java" } }, "highlight":{ "fields":{ "title":{} }, "pre_tags":"<font color=red>", "post_tags":"</font>", "fragment_size":4 }}

聚合查询

ES的聚合查询和MYSQL的聚合查询类型,ES的聚合查询相比Mysql要强大的多,ES提供的统计数据的方式多种多样

GET /store/_search{ "aggs":{ "agg":{ //名字 ”agg_type":{ "" //属性:值 } } }}

去重计数查询

GET /store/_search{ "aggs":{ "agg":{ //名字 "cardinality":{ "field":"price" } } }}

范围统计

统计一定范围内出现的文档个数,比如,针对某一个Feld的值在0-100,100-200, 200-300之间文档出现的个数分别是多少

范围统计可以针对普通的数值,针对时间类型,针对类型都可以做相应的统计.

range , data_range, ip_range

GET /store/_search{ "aggs":{ "agg":{ "range":{ "field": "price", "ranges": [ {"from": 10,"to":50} ] } }}

统计聚合

他可以帮你查询指定Fed的最大值,最小值,平均值,平方和,,,

GET /store/_search{ "aggs":{ "agg":{ "extended_stats":{ "field": "price" } } }}

更多apihttps://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics.html

地图检索

geo_distance: 直线距离检索方式

geo_bounding_box: 以两个点确定一个矩形,获取在矩形内的全部数据

geo_polygon: 以多个点(至少3个点),确定一个多边形,获取多边形内的全部数据

GET /map/_search{ "query":{ "geo_distance":{ "location":{ "lon": 123.51551, //经度 "lat": 421.215, //纬度 }, "distance":2000, // 距离米 "distance_type":"arc" //圆形范围 } }}
GET /map/_search{ "query":{ "geo_bounding_box":{ "location":{ "top_left": { "lon": 123.51551, //经度 "lat": 421.215, //纬度 }, "bottom_right":{ "lon": 123.51551, //经度 "lat": 421.215, //纬度 } } } }}
GET /map/_search{ "query":{ "geo_polygon":{ "location":{ "points": [ { "lon": 123.51551, //经度 "lat": 421.215, //纬度 }, { "lon": 123.51551, //经度 "lat": 421.215, //纬度 }, { "lon": 123.51551, //经度 "lat": 421.215, //纬度 } ]} } }}

杀死进程

killps -ef|grep Elasticsearch | grep -v grep|awk '{print $2}'

Kibana

wget https://artifacts.elastic.co/downloads/kibana/kibana-7.6.2-linux-x86_64.tar.gz

配置

配置项备注
elasticsearch.hosts: [“http://127.0.0.1:9200“]es地址