天天看点

ElasticSearch系列(二):基本数据操作(上)

作者:paulpei

一. 前期知识及环境准备

在正式学习ES的基本数据操作之前,需要了解一下以下相关的基本概念:

  1. 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工作正常

ElasticSearch系列(二):基本数据操作(上)

5.Kibana 检查

访问Kibana:http://192.168.246.134:5601

显示界面如下:

ElasticSearch系列(二):基本数据操作(上)

点击【Explore on my own】

ElasticSearch系列(二):基本数据操作(上)

点击左上角的菜单,选择【Management】下的【Dev Tools】,进入如下界面,之后的例子也将在此功能里面执行,并显示输出结果。

输入 如下: GET /

点击该行右边的箭头 ,发送请求,则在右边的显示区域会显示请求结果信息,如下图所示:

ElasticSearch系列(二):基本数据操作(上)

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

二.创建索引及文档

  1. 创建索引及文档

使用PUT方法来进行创建索引及文档

注: 以下所有 # 的部分,仅仅为了注释说明,执行的时候,请去掉,否则会报告错误。

例如:

PUT ddz/_doc/1 # 索引名:ddz 文档id:1

{

"uid":10001, # 文档字段:值

"nickname":"麦子",

"coin":3000,

"phone":13622445609,

"score":203

}

ElasticSearch系列(二):基本数据操作(上)

右边输出信息如下:

#! 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信息如下:

ElasticSearch系列(二):基本数据操作(上)

2.创建立即用于搜索的索引及文档

一般情况下,新写入的文档并不能马上被用于搜索,索引必须写入到 Segment 后才能被搜索到,需要等到 refresh 操作才可以。而在默认的情况下,refresh 一次的时间间隔是一秒。这也是通常所说的 Elasticsearch 可以实现秒级的搜索的由来。但,如果指定了强制 refresh 操作,则可以马上被用于搜索。

例如:

PUT ddz/_doc/2?refresh=true

{

"uid":10002,

"nickname":"鸽子",

"coin":34000,

"phone":17022448601,

"score":-33

}

ElasticSearch系列(二):基本数据操作(上)

右边输出信息如下:

{

"_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

}

ElasticSearch系列(二):基本数据操作(上)

右边输出信息如下:

{

"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

ElasticSearch系列(二):基本数据操作(上)

如果可以查找到索引信息,右边的输出信息,则显示查找到的索引信息。

{

"_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系列(二):基本数据操作(中)】

继续阅读