当前Elasticsearch版本号:7.3.2
Elasticsearch | 关系型数据库 |
---|---|
ES | 数据库 |
索引index | 表 |
文档 document | 行(记录) |
字段 fields | 列 |
分片(shard):
shard = primary shard(主分片)
把索引库拆分为多份,分别放在不同的节点上,比如有3个节点,3个节点的所有数据内容加在一起是一个完整的索引库。分别保存到三个节点上水平扩展,提高吞吐量。
备份(replica):
replica = replica shard(备份节点)
每个shard的备份。
将下载好的Elasticsearch上传至Linux服务器
目录介绍
修改核心配置文件 elasticearch.yml,config目录下
# 集群名
cluster.name: my-application
# 当前节点
node.name: node-1
# 索引目录
path.data: /opt/elasticsearch-7.3.2/data
# 日志
path.logs: /opt/elasticsearch-7.3.2/logs
# 允许所有IP
network.host: 0.0.0.0
# 符合master节点条件的节点,多个逗号分隔
cluster.initial_master_nodes: ["node-1"]
GET /_cluster/health
PUT /index_one
{
"settings":{
"index":{
# 分片数
"number_of_shards":"2",
# 副本数
"number_of_replicas":"0"
}
}
}
GET /index_one
GET /_cat/indices?v
DELETE /index_one
PUT /index_one
{
"mappings":{
"properties":{
"username":{
"type":"text", # 字符串类型
"index":true # 为该属性创建索引
},
"sign":{
"type":"text",
"index":true
},
"sex":{
"type":"keyword", # 不分词
"index":false # 不创建索引
}
}
}
}
GET /index_one/_analyze
{
"field":"username",
"text":"my name is DingWenhao"
}
PUT /index_one/_mapping
{
"properties":{
"name":{
"type":"long"
}
}
}
POST /index_one/_mapping
{
"properties":{
"username":{
"type":"text",
"index":true
},
"sign":{
"type":"text",
"index":true
},
"sex":{
"type":"keyword",
"index":false
}
}
}
# {索引名}/_doc/{索引ID}
POST /index_one/_doc/1
{
"id":"1",
"username":"ding wen hao",
"sign":"Java小白",
"sex":"男"
}
# 文档删除不是立即删除,文档还是保存在磁盘上,索引增长越来越多,才会把那些曾经标识过删除的,进行清理
DELETE /index_one/_doc/1
# 每次修改后,version会更改
POST /index_one/_doc/1/_update
{
"doc": {
"username": "ding ding ding"
}
}
# 每次修改后,version会更改
PUT /index_one/_doc/1
{
"id":"1",
"username":"ding wen hao ya ya",
"sign":"Java小白",
"sex":"男"
}
# {索引}/_doc/{id}
GET /index_one/_doc/1
返回数据说明:
_index:文档数据所属那个索引,理解为数据库的某张表即可。
_type:文档数据属于哪个类型,新版本使用 _doc 。
_id:文档数据的唯一标识,类似数据库中某张表的主键。可以自动生成或者手动指定。
_score:查询相关度,是否契合用户匹配,分数越高用户的搜索体验越高。
_version:版本号。
_source:文档数据,json格式。
# 其他方式
GET /index_one/_doc/_search
# 定制结果集
GET /index_one/_doc/1?_source=id,username
GET /index_one/_doc/_search?_source=id,username
# 判断文档是否存在
HEAD /index_one/_doc/1
_seq_no: 文档版本号,作用同version
_primary_term: 文档所在的位置
# 操作1
POST /index_one/_doc/{_id}/_update?if_seq_no={数值}&if_primary_term={数值}
{
"doc": {
"username": "ding ding ding hei"
}
}
# 操作2
POST /index_one/_doc/{_id}/_update?if_seq_no={数值}&if_primary_term={数值}
{
"doc": {
"username": "ding ding ding hei hei ya"
}
}
两个操作并发执行,仅有一个可执行成功
地址: https://github.com/medcl/elasticsearch-analysis-ik/releases
选择与Elasticsearch对应版本的进行下载即可
unzip elasticsearch-analysis-ik-7.3.2.zip -d /ik
测试中文分词
POST /_analyze
{
"analyzer": "ik_max_word",
"text": "你好呀,今天也要努力学习哟"
}
1. 在{es}/plugins/ik/config下,创建custom.dic
vi custom.dic
2. 添加内容
自定义即可,每个词汇需换行
3. 配置自定义扩展词典
vi IKAnalyzer.cfg.xml
配置:
custom.dic
4. 重启即可
创建索引 index_two
PUT /index_two
{
"settings":{
"index":{
"number_of_shards":"2",
"number_of_replicas":"0"
}
}
}
创建mapping
POST /index_two/_mapping
{
"properties": {
"id": {
"type": "long"
},
"age": {
"type": "integer"
},
"username": {
"type": "keyword"
},
"nickname": {
"type": "text",
"analyzer": "ik_max_word"
},
"money": {
"type": "float"
},
"desc": {
"type": "text",
"analyzer": "ik_max_word"
},
"sex": {
"type": "byte"
},
"birthday": {
"type": "date"
},
"face": {
"type": "text",
"index": false
}
}
}
添加五条测试数据
POST /index_two/_doc/1
{
"id":1,
"age":18,
"username":"丁文浩",
"nickname":"这个橘子超甜",
"money":"99.99",
"desc":"一个热爱学习的搬砖少年!",
"sex":"0",
"birthday":"1996-07-22",
"face":"XXX"
}
POST /index_two/_doc/2
{
"id":2,
"age":22,
"username":"张三",
"nickname":"舍我其谁",
"money":"25.9",
"desc":"帮我带一瓶冰阔落",
"sex":"0",
"birthday":"1992-01-22",
"face":"(*≧m≦*)"
}
POST /index_two/_doc/3
{
"id":3,
"age":44,
"username":"项羽",
"nickname":"至今思项羽,不肯过江东",
"money":"199.9",
"desc":"生当作人杰,死亦为鬼雄",
"sex":"0",
"birthday":"1969-03-12",
"face":"ha ha ha ~"
}
POST /index_two/_doc/4
{
"id":4,
"age":37,
"username":"吕布",
"nickname":"我的貂蝉在哪里!",
"money":"199.9",
"desc":"此时,貂蝉还在骑马赶来的路上",
"sex":"0",
"birthday":"1962-03-12",
"face":"lue lue lue~"
}
POST /index_two/_doc/5
{
"id":5,
"age":45,
"username":"段天涯",
"nickname":"我全都要",
"money":"36.6",
"desc":"东瀛剑法",
"sex":"0",
"birthday":"1964-03-12",
"face":"xiu xiu xiu"
}
# keyword不会被倒排索引,不会被分词
GET /index_two/_doc/_search?q=desc:剑法
GET /index_two/_doc/_search?q=desc:剑法&q=nickname:橘子
QueryString用的很少,一旦参数复杂就难以构建,所以大多查询都会使用dsl来进行查询更好。
# 查询
GET /index_two/_doc/_search
{
"query":{
"match": {
"nickname": "好甜呀"
}
}
}
# 判断某个字段是否存在
GET /index_two/_doc/_search
{
"query":{
"exists": {
"field": "nickname"
}
}
}
# 在索引中查询所有的文档
GET /index_two/_doc/_search
# 或 _source展示部分字段
POST /index_two/_doc/_search
{
"query": {
"match_all": {}
},
"_source": [
"id",
"username",
"desc"
]
}
# 或
POST /index_two/_doc/_search
{
"query": {
"match": {
"desc":"热爱学习的剑法"
}
}
}
# 带分页的查询
POST /index_two/_doc/_search
{
"query": {
"match_all": {}
},
"_source": [
"id",
"username",
"desc"
],
"from": 0,
"size": 5
}
# term 作为一整个关键词去搜索,match则是进行分词后搜索
POST /index_two/_doc/_search
{
"query": {
"term": {
"desc":"少年"
}
}
}
# 或 多词汇搜索
{
"query": {
"terms": {
"desc":["少年","剑法","帮我"]
}
}
}
match:分词后只要有匹配就返回
match_phrase:分词结果必须在text字段分词中都包含,而且顺序必须相同,而且必须都是连续的。
slop:允许词语间跳过的数量
POST /index_two/_doc/_search
{
"query": {
"match_phrase": {
"desc": {
"query": "热爱 学习 少年",
"slop": 4
}
}
}
}
operator :
or:搜索内容分词后,只要存在一个词语匹配就展示结果
and:搜索内容分词后,都要满足词语匹配
POST /index_two/_doc/_search
{
"query": {
"match": {
"desc": {
"query": "喜欢冰阔乐的少年爱学习",
"operator": "or"
}
}
}
}
相当于:
select * from index_two where desc='冰阔乐' or desc='学习'
POST /index_two/_doc/_search
{
"query": {
"match": {
"desc": {
"query": "热爱学习的少年",
"operator": "and"
}
}
}
}
相当于:
select * from index_two where desc='热爱' and desc='学习' and desc='的' and desc='少年'
minimum_should_match:
最低匹配精度,至少有[分词后的词语个数]x百分百,得出一个数据值取整。举个例子:当前属性设置为 70 ,若一个用户查询有10个词语,那么匹配度按照 10x70%=7,则desc中至少需要有7个词语匹配,就展示;若分词后有8个,则 8x70%=5.6,则desc中至少需要有5个词语匹配,minimum_should_match也能设置具体的数字,表示个数
POST /index_two/_doc/_search
{
"query": {
"match": {
"desc": {
"query": "热爱学习的少年",
"minimum_should_match": "60%"
}
}
}
}
根据id批量查询
POST /index_two/_doc/_search
{
"query":{
"ids":{
"type":"_doc",
"values" : ["1", "4"]
}
}
}
multi_match:
满足使用match在多个字段中进行查询的需求
POST /index_two/_doc/_search
{
"query": {
"multi_match": {
"query": "段天涯",
"fields": [
"username",
"desc"
]
}
}
}
boost:
权重,为某个字段设置权重,权重越高,文档相关性得分就越高。通畅来说搜索商品名称要比商品简介的权重更高。
username^10 代表搜索提升10倍相关性,也就是说用户搜索的时候其实以这个username为主,desc为辅,username的匹配相关度当然要提高权重比例了。
POST /index_two/_doc/_search
{
"query": {
"multi_match": {
"query": "段天涯",
"fields": [
"username^10",
"desc"
]
}
}
}
可以组合多重查询
# 多个字段汇总有[段天涯]并且sex为[0],birthday[1964-03-12]
POST /index_two/_doc/_search
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "段天涯",
"fields": [
"desc",
"username"
]
}
},
{
"term": {
"sex": 0
}
},
{
"term": {
"birthday": "1964-03-12"
}
}
]
}
}
}
对搜索出来的结果进行数据过滤。不会到es库里去搜,不会去计算文档的相关度分数,所以过滤的性能会比较高,过滤器可以和全文搜索结合在一起使用。
post_filter元素是一个顶层元素,只会对搜索结果进行过滤。不会计算数据的匹配度相关性分数,不会根据分数去排序,query则相反,会计算分数,也会按照分排序
使用场景:
query:
根据用户搜索条件检索匹配记录
post_filter:
用于查询后,对结果数据的筛选
gte:大于等于
lte:小于等于
gt:大于
lt:小于
(除此以外还能做其他的match等操作也行)
# 筛选结果中账户金额大于50元,小于200元的用户
POST /index_two/_doc/_search
{
"query": {
"match": {
"desc": "爱学习的少年"
}
},
"post_filter": {
"range": {
"money": {
"gt": 50,
"lt": 200
}
}
}
}
es的排序同sql,可以desc也可以asc。也支持组合排序。
POST /index_two/_doc/_search
{
"query": {
"match": {
"desc": "爱学习的少年"
}
},
"post_filter": {
"range": {
"money": {
"gt": 50,
"lte": 200
}
}
},
"sort": [
{
"age": "desc"
},
{
"money": "desc"
}
]
}
对文本排序
由于文本会被分词,所以往往要去做排序会报错,通常我们可以为这个字段增加额外的一个附属属性,类型为keyword,用于做排序。
# 创建新的索引
POST /index_three/_mapping
{
"properties": {
"id": {
"type": "long"
},
"nickname": {
"type": "text",
"analyzer": "ik_max_word",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
POST /index_two/_doc/_search
{
"query": {
"match": {
"desc": "爱学习的少年"
}
},
"highlight": {
"pre_tags": [
""
],
"post_tags": [
""
],
"fields": {
"desc": {}
}
}
}
prefix :
根据前缀去查询
POST /index_two/_doc/_search
{
"query": {
"prefix": {
"username": "ding"
}
}
}
fuzzy :
模糊搜索,并不是指的sql的模糊搜索,而是用户在进行搜索的时候的打字错误现象,搜索引擎会自动纠正,然后尝试匹配索引库中的数据。
POST /index_two/_doc/_search
{
"query": {
"fuzzy": {
"username": "丁文号"
}
}
}
# 多字段搜索
{
"query": {
"multi_match": {
"fields": [
"username",
"desc"
],
"query": "丁文号",
"fuzziness": "AUTO"
}
}
}
wildcard:
占位符查询,性能较差
POST /index_two/_doc/_search
{
"query": {
"regexp": {
"username": "jav[a-z]*"
}
}
}
# 查询设置
GET /index_two/_settings
PUT /index_two/_settings
{
"index.max_result_window": "20000"
}
一次性查询1万+数据,往往会造成性能影响,因为数据量太多了。这个时候可以使用滚动搜索,也就是 scroll 滚动搜索可以先查询出一些数据,然后再紧接着依次往下查询。在第一次查询的时候会有一个滚动id,相当于一个 锚标记 ,随后再次滚动搜索会需要上一次搜索,根据这个进行下一次的搜索请求。每次搜索都是基于一个历史的数据快照,查询数据的期间,如果有数据变更,那么和搜索是没有关系的.
scroll=1m,相当于是一个session会话时间,搜索保持的上下文时间为1分钟。
POST /index_two/_search?scroll=3m
{
"query": {
"match_all": {}
},
"sort": [
"_doc"
],
"size": 5
}
POST /_search/scroll
{
"scroll": "3m",
"scroll_id": "上一个请求返回的scroll_id"
}
bulk操作和以往的普通请求格式有区别。不要格式化json,不然就不在同一行了,这个需要注意。
{ action: { metadata }}\n
{ request body }\n
{ action: { metadata }}\n
{ request body }\n
...
说明:
{ action: { metadata }}
代表批量操作的类型,可以是新增、删除或修改
\n
是每行结尾必须填写的一个规范,每一行包括最后一行都要写,用于es的解析
{ request body }
是请求body,增加和修改操作需要,删除操作则不需要
批量操作的类型 :
action 必须是以下选项之一:
create:如果文档不存在,那么就创建它。存在会报错。发生异常报错不会影响其他操作。
index:创建一个新文档或者替换一个现有的文档。
update:部分更新一个文档。
delete:删除一个文档。
metadata中需要指定要操作的文档的 _index 、 _type 和 _id , _index 、 _type 也可以在url中指定
注:最后一行也需要换行
示例一:create新增文档数据,在metadata中指定index以及type
POST /_bulk
{"create": {"_index": "index_two", "_type": "_doc", "_id": "1001"}}
{"id": "1001", "username": "username1001"}
{"create": {"_index": "index_two", "_type": "_doc", "_id": "1002"}}
{"id": "1002", "username": "username1002"}
{"create": {"_index": "index_two", "_type": "_doc", "_id": "1003"}}
{"id": "1003", "username": "username1003"}
示例二:create创建已有id文档,在url中指定index和type
POST /index_two/_doc/_bulk
{"create": {"_id": "1003"}}
{"id": "1003", "username": "username1003"}
{"create": {"_id": "1004"}}
{"id": "1004", "username": "username1004"}
{"create": {"_id": "1005"}}
{"id": "1005", "username": "username1005"}
示例三:index创建,已有文档id会被覆盖,不存在的id则新增
POST /index_two/_doc/_bulk
{"index": {"_id": "1005"}}
{"id": "1005", "username": "index-username1005"}
{"index": {"_id": "1006"}}
{"id": "1006", "username": "username1006"}
{"index": {"_id": "1007"}}
{"id": "1007", "username": "username1007"}