一. 前期知识及环境准备
在正式学习ES的基本数据操作之前,需要了解一下以下相关的基本概念:
- JSON
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于 ECMAScript(European Computer Manufacturers Association, 欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成。在 Elasticsearch 中,所以的数据都是以 JSON 的格式来进行表述的。
2.REST
REST 即表述性状态传递(Representational State Transfer,简称 REST)是 Roy Fielding 博士在2000年他的博士论文中提出来的一种软件架构风格。REST 是一种规范。即参数通过封装后进行传递,响应也是返回的一个封装对象。
可以通过使用 REST 接口来对 Elasticsearch 进行操作,对数据进行增加(Create),查询(Read),更新(Update)及删除(Delete),也就是通常说的 CRUD。
Elasticsearch 里的接口都是通过 REST 接口来实现的。
方法 | 用法 |
GET | 读取数据 |
POST | 插入数据 |
PUT | 更新数据,或如果是一个新的 id,则插入数据 |
DELETE | 删除数据 |
3.curl
可以使用 curl 将请求从命令行提交到本地 Elasticsearch 实例。对 Elasticsearch 的请求包含与任何 HTTP 请求相同的部分:
curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
使用以下变量:
<VERB> :适当的 HTTP 方法或动词。 例如,GET,POST,PUT,HEAD 或 DELETE
<PROTOCOL>:http 或 https。 如果你在 Elasticsearch 前面有一个 HTTPS 代理,或者你使用 Elasticsearch 安全功能来加密 HTTP 通信,请使用后者
<HOST>:Elasticsearch 集群中任何节点的主机名。 localhost 用于本地计算机上的节点
<PORT>:运行 Elasticsearch HTTP 服务的端口,默认为9200
<PATH>:API 端点,可以包含多个组件,例如 _cluster/stats 或 _nodes/stats/jvm
<QUERY_STRING>:任何可选的查询字符串参数。 例如,?pretty 将漂亮地打印 JSON 响应以使其更易于阅读
<BODY>:JSON 编码的请求正文(如有必要)
如果启用了 Elasticsearch 安全功能,则还必须提供有权运行 API 的有效用户名(和密码)。 例如,使用 -u 或 --u cURL 命令参数。比如:
curl -u elastic:password -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
4.Elasticsearch 检查
访问Elasticsearch :http://192.168.246.134:9200/
返回如下信息,证明Elasticsearch工作正常
5.Kibana 检查
访问Kibana:http://192.168.246.134:5601
显示界面如下:
点击【Explore on my own】
点击左上角的菜单,选择【Management】下的【Dev Tools】,进入如下界面,之后的例子也将在此功能里面执行,并显示输出结果。
输入 如下: GET /
点击该行右边的箭头 ,发送请求,则在右边的显示区域会显示请求结果信息,如下图所示:
GET /
和
http://192.168.246.134:9200/ 看到的信息一致。
6.Elasticsearch数据类型
ES的数据类型比较多,请见下表:
Types | 数据类型 | 数据类型 |
Common Types | binary | binary |
boolean | boolean | |
Keywords | keyword | |
constant_keyword | ||
wildcard | ||
Numbers | long | |
integer | ||
short | ||
byte | ||
double | ||
float | ||
half_float | ||
scaled_float | ||
unsigned_long | ||
Dates | date | |
date_nanos | ||
alias | alias | |
Objects and relational | object | |
flattened | flattened | |
nested | nested | |
join | join | |
Structured | Range | long_range |
integer_range | ||
float_range | ||
double_range | ||
date_range | ||
ip_range | ||
ip | ip | |
version | version | |
Aggregate | aggregate_metric_double | aggregate_metric_double |
histogram | histogram | |
Text search | text | text |
match_only_text | ||
completion | completion | |
search_as_you_type | search_as_you_type | |
token_count | token_count | |
Document ranking | dense_vector | dense_vector |
sparse_vector | sparse_vector | |
rank_feature | rank_feature | |
rank_features | rank_features | |
Spatial | geo_point | geo_point |
geo_shape | geo_shape | |
point | point | |
shape | shape | |
Other | percolator | percolator |
每一种数据类型的应用,后续章节会逐步涉及,这里仅仅先做个大概了解。
具体请参见:
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/mapping-types.html
二.创建索引及文档
- 创建索引及文档
使用PUT方法来进行创建索引及文档
注: 以下所有 # 的部分,仅仅为了注释说明,执行的时候,请去掉,否则会报告错误。
例如:
PUT ddz/_doc/1 # 索引名:ddz 文档id:1
{
"uid":10001, # 文档字段:值
"nickname":"麦子",
"coin":3000,
"phone":13622445609,
"score":203
}
右边输出信息如下:
#! Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-minimal-setup.html to enable security.
注:因未开启安全认证,所以会有如下的提示信息,暂时忽略此信息。
{
"_index" : "ddz", # 索引名
"_type" : "_doc", # Type名
"_id" : "1", # ID
"_version" : 2, # 版本,数据更改一次,此值会自动增加1,此处为了演示,执行了2次
"result" : "updated", # 更新
"_shards" : {
"total" : 2, # 两个shards,一个是Primary,另一个是Replica
"successful" : 1, # 成功
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
以上例子,创建了一个新的索引及文档,在此例中,并未事先确定字段的数据类型,但Elasticsearch 会根据所输入字段的数据自动猜测它的数据类型,比如上面的 nickname被认为是 text 类型,而coin将被猜测为long类型。这种方式称之为 schema on write。
在 Elasticsearch 的术语中,mapping 被称作为 Elasticsearch 的数据 schema。文档中的所有字段都需要映射到 Elasticsearch 中的数据类型。 mapping 指定每个字段的数据类型,并确定应如何索引和分析字段以进行搜索。 在 SQL 数据库中定义表时,mapping 类似于 schema。
执行:GET ddz/_mapping 可以查看mapping信息如下:
2.创建立即用于搜索的索引及文档
一般情况下,新写入的文档并不能马上被用于搜索,索引必须写入到 Segment 后才能被搜索到,需要等到 refresh 操作才可以。而在默认的情况下,refresh 一次的时间间隔是一秒。这也是通常所说的 Elasticsearch 可以实现秒级的搜索的由来。但,如果指定了强制 refresh 操作,则可以马上被用于搜索。
例如:
PUT ddz/_doc/2?refresh=true
{
"uid":10002,
"nickname":"鸽子",
"coin":34000,
"phone":17022448601,
"score":-33
}
右边输出信息如下:
{
"_index" : "ddz",
"_type" : "_doc",
"_id" : "2",
"_version" : 1, # 版本为1
"result" : "created", # 创建
"forced_refresh" : true, # 强制刷新
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}
3.同步创建索引及文档
上面的方式可以强制使 Elasticsearch 进行 refresh 的操作,但是频繁的进行这种操作,可以使我们的 Elasticsearch 变得非常慢,显然,这不是所期望的。
故此,也提供了另外一种同步的方式,通过设置 refresh=wait_for,等待下一个 refresh 周期发生完后,才返回。这样可以确保在调用上面的接口后,马上可以搜索到刚才录入的文档:
例如:
PUT ddz/_doc/3?refresh=wait_for
{
"uid":10003,
"nickname":"栗子",
"coin":31000,
"phone":17122359451,
"score":562
}
4.新建索引及文档
一般来说,在写入文档时,如果该文档的 ID 已经存在,那么就会更新现有的文档;如果该文档从来没有存在过,那么就创建新的文档。如果,这不是所期望的处理方式,而是,期望存在的时候,再次写入,可以报告错误,则可以借助 _create 端点接口实现。
例如:
PUT ddz/_create/1
{
"uid":10001,
"nickname":"麦子",
"coin":3000,
"phone":13622445609,
"score":203
}
右边输出信息如下:
{
"error" : {
"root_cause" : [
{
"type" : "version_conflict_engine_exception",
"reason" : "[1]: version conflict, document already exists (current version [2])",
"index_uuid" : "0PgbkAV8RYumrBDA268xxw",
"shard" : "0",
"index" : "ddz"
}
],
"type" : "version_conflict_engine_exception",
"reason" : "[1]: version conflict, document already exists (current version [2])",
"index_uuid" : "0PgbkAV8RYumrBDA268xxw",
"shard" : "0",
"index" : "ddz"
},
"status" : 409
}
下面命令效果和上面相同
PUT ddz/_doc/1?op_type=create
{
"uid":10001,
"nickname":"麦子",
"coin":3000,
"phone":13622445609,
"score":203
}
5.查找文档:
上面的例子创建了索引文档,需要查找,验证是否正确。可以借助GET方法实现。
执行:
GET ddz/_doc/1
如果可以查找到索引信息,右边的输出信息,则显示查找到的索引信息。
{
"_index" : "ddz",
"_type" : "_doc",
"_id" : "1",
"_version" : 3,
"_seq_no" : 5,
"_primary_term" : 1,
"found" : true, # 标记为true,找到
"_source" : {
"uid" : 10001,
"nickname" : "麦子",
"coin" : 3000,
"phone" : 13622445609,
"score" : 203
}
}
反之,如果查不到索引信息,输出信息如下:
{
"_index" : "ddz",
"_type" : "_doc",
"_id" : "13",
"found" : false # 标记为false,未找到
}
后续见【ElasticSearch系列(二):基本数据操作(中)】