elasticsearch学习笔记整理(含下面总结的面试题)
elasticsearch是一个全文检索的搜索引擎
Elasticsearch是一个基于Lucene的搜索服务器
ES可以做全文检索、模糊查询(搜索)、数据分析(提供分析语法,例如聚合)。
es是不能使用root用户进行启动的,要新创建一个用户才行
创建用户:useradd qianfeng
设置密码:passwd qianfeng
早期es的结构
需要注意:Type类型,在Elasticsearch6.x的版本中已经被标记为废弃状态,在Elasticsearch7的版本中,已经被彻底移除。数据直接存储于Index,因此Index可以类比于关系型数据库中的数据库或者表的概念。
为了便于安装后期的操作以及效果展示,推荐安装head插件。(以下为head插件安装之后的效果图)
我们可以创建索引,同时制定分片数和副本数。
主分片和副分片图形展示
# 在一个没有索引的空集群中运行如上查询,将返回这些信息:
curl -X GET http://qianfeng01:9200/_cluster/health // qianfeng01表示第一个node节点的名称。连接es集群的时候,随便找一台节点就能连接上整个es集群。
创建索引
curl -X PUT http://qianfeng01:9200/bigdata2 // 创建名称为bigdata2的索引
查看索引中的所有数据
curl -X GET "http://qianfeng01:9200/route_test/_search?pretty" // pretty表示以格式化的方式进行数据的展示
指定id为c
curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/route_test/_doc/c?routing=key1&refresh" -d '{"data":"C"}' // -H携带请求头-d表示指定后面要发送的数据,refresh表示能够尽快的将这条数据序列化出来
查看索引名为route_test的分片情况
curl -X GET "http://qianfeng01:9200/_cat/shards/route_test?v" // v表示显示列名
动态修改副本因子
curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/bigdata/_settings -d '{"number_of_replicas":3}' // _settings表示设置配置信息
查看所有索引
curl -X GET "http://qianfeng01:9200/_cat/indices?v // _cat表示查看信息 indices表示索引
查看某个索引的具体配置信息
curl -X GET "http://qianfeng01:9200/bigdata // 查看名称为bigdata索引的配置信息
删除索引
curl -X DELETE "http://qianfeng01:9200/bigdata // 删除名称为bigdata的索引
创建文档
curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/bigdata/_doc -d '{"title":"java","content","java 从入门到入土"}' // 向索引bigdata中插入一条文档,_doc表示文档
批量添加文档
curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/bigdata/_bulk -d
'
{"title":"java","content","java 从入门到入土"}
{"title":"php","content","世界最好的语言"}
'
#使用读取文件的方式添加文档
curl -H "Content-Type: application/json" -X POST "http://qianfeng01:9200/bigdata/_bulk" --data-binary "@data.json"
修改文档
curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/bigdata/_doc/101 -d '{"title":"java"}' // 修改101的数据,有则修改,没有就创建
curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/bigdata/_doc/101/_update -d '{"title":"java"}' // 修改101的数据,只修改title字段,其他字段不修改
删除文档
curl -X DELETE "http://qianfeng01:9200/bigdata/_doc/101 // 删除docid为101的文档
检索文档
curl -X GET "http://qianfeng01:9200/bigdata/_doc/101?pretty // 查找docid为101的文档
检索title中包含HDFS的文档
curl -X GET "http://qianfeng01:9200/test/_search?q=title:HDFS&pretty"
检索title中包含HDFS的文档,只显示title和text两列,如果某条数据没有text列,就不进行展示
curl -X GET "http://qianfeng01:9200/test/_search?q=title:HDFS&_source=title,text&pretty"
分页查询
curl -X GET "http://qianfeng01:9200/test/_search?from=1&size=2&pretty"
批量检索
curl -H "Content-Type:application/json" -X GET "http://qianfeng01:9200/_mget?
pretty" -d \
'
{
"docs": [
{
"_index": "bigdata",
"_id": "1",
"_source": "name,age"
},
{
"_index": "test",
"_id": "1",
"_source": "name"
}
]
}
'
指定路由的方式插入文档 routing=key1 这个key1可以随便写
curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/route_test/_doc/c?routing=key1&refresh" -d '{"data":"C"}'
也就是说比方我再来一条数据,同样指定了 routing=key1,那么这条数据也会保存到相同的分片当中
curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/route_test/_doc/d?routing=key1&refresh" -d '{"data":"Cc"}'
自定义routing后会导致一个问题:docid不再全局唯一!此时就需要自己手动去维护docid了。比如说我们可以通过java代码的方式进行单独的处理。
如果自定义了routing字段的话,一般doc的增删改查操作都要加上routing参数以保证一致性。为此,
Elasticsearch 7以上的版本中,在mapping中提供了一个选项("required": true),可以强制检查doc的
增删改查操作是否添加了routing参数,如果没有添加就会报错。
解决自定义路由产生的数据倾斜
shard_num = (hash(_rounting) + hash(_id) % routing_partition_size) % num_primary_shards
在同一个节点上面创建副本是没有任何意义的,创建副本主要的目的就是为了保证高可用性的。
比如我一共有3台机子,3个节点。创建好了N个主分片,创建副分片的数量只能是3-1个,因为要部署到不同的机子上面,如果创建的副分片的数量多余机子的数量,那么多余出来的是没有任何意义的。这个时候我们会看到集群的状态变成了yellow了。
索引创建完成之后,我们是可以再次修改副分片的数量的,但是主分片的数量是不能修改的,修改的话是会报错的。
Mapping类比于关系型数据库中的Schema,表结构,创建完索引之后,我们可以对表结构进行设置。
mapping可以定义index(索引)下面字段的名称和字段的类型
curl -X GET "http://qianfeng01:9200/bigdata/_mapping?pretty"
{
"bigdata" : {
"mappings" : {
"properties" : {
"content" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"date" : {
"type" : "date",
"format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"
},
"description" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"text" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"title" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
创建完索引的时候,可以对mapping的dynamic参数进行设置
true:动态映射, 动态映射,新增的一条文档可以被索引,可以搜索到。新增的字段也可以被索引,可以被搜索到,Mapping也会同步更新。
false:自定义映射,自定义映射,新增的一条文档可以被索引,可以被搜索到。文档中已经被定义到Mapping中的字段可以被索引,新增的字段无法被索引,将会被丢弃。
也就是说使用命令的方式是能够查询出新增的字段的,但是在head插件的页面上是看不到新增的字段的。
strict:数据写入直接出错
copy_to 将该字段的值复制到目标字段中,该字段不会出现在source中,只用来搜索
curl -H "Content-Type:application/json" -X PUT "http://qianfeng01:9200/my_index2" -d \
' // 将first_name和last_name字段的值赋值给full_name
{
"mappings": {
"properties": {
"first_name": {
"type": "text",
"copy_to": "full_name"
},
"last_name": {
"type": "text",
"copy_to": "full_name"
},
"full_name": {
"type": "text"
}
}
}
}
'
直接通过id查询是不显示full_name的。可以通过下面的方式进行查询
curl -H "Content-Type:application/json" -X GET "http://qianfeng01:9200/my_index2/_doc/1?pretty" -d \
'{
"query": {
"match": {
**"full_name": "John Smith"**
}
}
}'
显示结果中也是不包含full_name字段的,只是用来进行组合查询用的。
index属性控制当前字段是否被索引,默认值为true,即这条消息可以被索引。false表示不被索引。
curl -H "Content-Type: application/json" -X PUT "http://qianfeng01:9200/my_index3" -d \
'
{
"mappings": {
"properties": {
"idcard": {
"type": "text",
"index": false // 指定text字段不能被索引
}
}
}
}
'
查看Mapping信息
curl -X GET "http://qianfeng01:9200/my_index3/_mapping?pretty"
在head插件中,高亮颜色的是主分片,暗淡一点的是副分片。
总结:要给面试官说出
elasticsearch是一个全文检索的搜索引擎
Elasticsearch是一个基于Lucene的搜索服务器。
ES可以做全文检索、模糊查询(搜索)、数据分析(提供分析语法,例如聚合)。
主分片、副分片
索引创建完了之后,我们是不能够修改主分片的数量,但是可以修改副分片的数量。
索引里面包含文档,文档里面包含字段
添加文档的时候可以一条条添加,也可以批量添加,也可以使用读取配置文件的方式添加。
修改文档的时候和添加文档的时候使用的命令是一样的,说白了就是有那个字段就修改,没有就相当于是添加操作。
可以使用指定routing=key1 的方式来使得两条记录都能够插入到相同的主分片中。
创建完索引之后,我们可以对表结构进行设置。我们可以指定mapping可以定义index(索引)下面字段的名称和字段的类型。
创建完索引的时候,可以对mapping的dynamic参数进行设置
true:动态映射, 动态映射,新增的一条文档可以被索引,可以搜索到。新增的字段也可以被索引,可以被搜索到,Mapping也会同步更新。
false:自定义映射,自定义映射,新增的一条文档可以被索引,可以被搜索到。文档中已经被定义到Mapping中的字段可以被索引,新增的字段无法被索引,将会被丢弃。也就是说使用命令的方式是能够查询出新增的字段的,但是在head插件的页面上是看不到新增的字段的。
strict:数据写入直接出错。
copy_to 将该字段的值复制到目标字段中,该字段不会出现在source中,只用来搜索。
mapping中的index属性控制当前字段是否被索引,默认值为true,即这条消息可以被索引。false表示不被索引。
ES聚合查询(面试有被问到)
range terms interval max min等等