hello,大家好,我是 Jackpop,硕士毕业于哈尔滨工业大学,曾在华为、阿里等大厂工作,如果你对升学、就业、技术提升等有疑惑,不妨交个朋友:
我是Jackpop,我们交个朋友吧!
在前面这一部分,我已经解释了 ElasticSearch 的基础知识及其工作原理。
在这一部分,我们将学习如何在 ElasticSearch 中执行搜索。
CRUD
在开发过程中,主要都在围绕着数据的 CRUD 进行处理,具体来说就是:
C – Create
R – Retrieve or Read
U – Update
D – Delete
下表将每个 CRUD 命令与其各自的 ElasticSearch HTTP / REST 命令进行了一一对应,
上一篇文章中,我们学习了 Kibana,接下来,就切换到 Kibana 的控制台。
创建索引
通过如下命令,创建一个 flight 索引:
PUT /flight
GET /_cluster/health
复制代码
请注意,现在群集的运行状况已从绿色变为黄色。 发生这种情况是因为我们仅运行一个 Elasticsearch 实例。 单节点群集具有完整的功能,但是无法将数据复制到其他节点以提供弹性。 副本分片必须有其他可用节点,群集状态才能变为绿色。 如果群集状态为红色,则标识某些数据不可用。
为了解决这个问题,您需要安装另一个同样的 Elasticsearch,并在 elasticsearch.yml 中更改 node.name; 两个实例中的 cluster.name 必须保持相同(默认为 elasticsearch)。
另一种方法是在命令行上将配置参数传递给 Elasticsearch。
bin/elasticsearch -Enode.name=node-2 -Epath.data=./node-2/data -Epath.logs=./node-2/logs
GET /_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open flight w696u4y3SYWuGW--8VzW6Q 1 1 0 0 208b 208b
复制代码
创建文档
下面,向我们的索引添加一些示例数据:
PUT /flight/_doc/1
{
"Icao":"A0835D",
"Alt":2400,
"Lat":39.984322,
"Long":-82.925616
}
复制代码
也可以使用 curl 命令:
curl -X PUT "localhost:9200/flight/_doc/1?pretty" -H 'Content-Type: application/json' -d'
{
"Icao":"A0835D",
"Alt":2400,
"Lat":39.984322,
"Long":-82.925616
}'
复制代码
在这种情况下,ElasticSearch 将为我们的文档生成一个自动 ID。 这是 ElasticSearch 返回的结果:
Content-Type 对于查询成功至关重要, 我们创建了一个 ID = 1 的新排期。我们也可以使用 POST 代替 PUT,但是在这种情况下,我们无法传递 ID。
在这种情况下,ElasticSearch 将为我们的文档生成一个自动 ID。
下面是 ElasticSearch 返回的结果:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "flight",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"Icao" : "A0835D",
"Alt" : 2400,
"Lat" : 39.984322,
"Long" : -82.925616
}
}
]
}
}
复制代码
结果文档存储在键值_source 内。
删除文档
如果你知道文档索引,可以直接通过索引进行删除:
删除索引
通过下方命令删除索引:
批量导入数据
我们的方案是处理航班数据,理想情况下,这些数据是从多个传感器(雷达)实时获得的,但是由于这很难实现。
因此,我们将使用可从此处下载的批量历史飞行数据。
在下载批处理文件的目录中,发送以下命令(每个.json 文件):
curl -H "Content-Type: application/x-ndjson" -XPOST http://localhost:9200/flights/_bulk --data-binary "@2016-07-01-1300Z.json"
复制代码
请注意,内容类型是 application/x-ndjson,而不是 application/x-json。
另外,请注意,我们将数据表示为二进制以便保留换行符。
磁瓦 ElasticSearch 需要 json 文档满足特定格式:
{"index":{"_id":4800770}}
{"Rcvr":1,"HasSig":false,"Icao":"494102", "Bad":false,"Reg":"CS-PHB", ...}
...
复制代码
这意味着你必须将每个下载的.json 文件转换为上述格式。
如果你不想花时间手动修改.json 文档,则在下一篇文章中,我们将开发一个 Java 程序来解析它们,并使用 ElasticSearch 的 REST API 将文件插入 ElasticSearch 中。
搜索查询
ElasticSearch 是一款搜索相关的工具,它允许你进行符合条件的搜索查询。
GET /flight/_search?pretty
{ "query": {
"match_all" : {
}
}
}
复制代码
上面的搜索查询匹配索引对应的所有文档。 也可以这样简化:
下面是根据给定字段 Icao 进行查询:
GET /flight/_search?pretty
{ "query": {
"match" : {
"Icao" : "A0835D"
}
}
}
复制代码
也可以用嵌入 URL 进行搜索:
GET /flight/_search?q=Icao:A0835D
复制代码
也可以这样写:
GET /flight/_search?pretty
{ "query": {
"query_string": {
"query": "Icao:A0835D"
}
}
}
复制代码
除了“match”和“query_string”以外,还可以使用“term”。 使用“ term”表示精确匹配。
GET /flight/_search?pretty
{ "query": {
"term": {
"Mil": true
}
}
}
复制代码
你也可以使用“term”来搜索值数组。
除此之外,还可以使用通配符“wildcard”进行搜索,包括*/?。
GET /flight/_search?pretty
{ "query": {
"wildcard": {
"Call": "NJ*"
}
}
}
复制代码
更新文档
如果你知道索引的 ID,可以通过_updateAPI 进行更新。
POST /flight/_update/4800770
{
"doc": {
"Mil": true
}
}
复制代码
使用上述命令,我们也可以将新字段添加到文档中。
附带说明一下,ElasticSearch 文档是不可变的!
因此,当我们请求更新文档时,ElasticSearch 会在后台进行操作,它检索文档,更改其字段并为具有相同 ID 的文档重新索引,从而对它进行替换。
可以使用脚本发送更复杂的查询,
POST /flight/_update/4800770
{
"script": {
"source": "ctx._source.FlightsCount++"
}
}
复制代码
ctx 表示上下文。
还有许多其他更新文档的方法,例如,upserts,即根据文件是否已存在有条件地更新或插入文件。
POST /flight/_update/4800771
{
"script": {
"source": "ctx._source.FlightsCount++"
},
"upsert": {
"Rcvr":1,
"HasSig":false,
"Icao":"AE4839",
...
},
}
复制代码
删除文档
使用_delete_by_query API 可以删除文档:
POST /flight/_delete_by_query
{
"query": {
"match_all": {}
}
}
复制代码
批量查询
批量 API 可帮助我们通过一个查询对许多文档执行同样的操作。
该 API 包含 4 个动作:索引,创建,更新,删除:
POST /_bulk
{ "index": { "_index" : "flight", "_id": 10519389 } }
{ "Rcvr":1,"HasSig":true,"Sig":0,"Icao":"A0835D","Bad":false, ... }
{ "create": { "_index" : "flight", "_id": 4800770 } }
{"Rcvr":1,"HasSig":false,"Icao":"494102","Bad":false, ... }
{ "update": { "_index" : "flight", "_id": 4800770 } }
{ "doc": {"Mil": true } }
{ "delete": { "_index" : "flight", "_id": 4800770 } }
复制代码
索引和创建操作之间的区别如下:如果文档已经存在,则创建将引发错误,而索引将替换文档。
如果批量查询要针对相同的索引运行,那么我们可以像这样简化查询:
POST /flight/_bulk
{ "index": { "_id": 10519389 } }
{ "Rcvr":1,"HasSig":true,"Sig":0,"Icao":"A0835D","Bad":false, ... }
{ "create": { "_id": 4800770 } }
{"Rcvr":1,"HasSig":false,"Icao":"494102","Bad":false, ... }
{ "update": { "_id": 4800770 } }
{ "doc": {"Mil": true } }
{ "delete": { "_id": 4800770 } }
复制代码
映射
ElasticSearch 是如何映射数据的呢?
动态映射意味着没有明确定义映射,或者至少没有为某些字段定义。
ElasticSearch 是通过检查文档字段的值类型来完成的。
要查看数据映射,请在 Kibana 中执行以下内容:
我们也可以通过下方命令手动添加映射关系,
PUT /flight/_mapping
{
"properties": {
"location": {
"type": "geo_point"
}
}
}
复制代码
请注意,一旦创建了字段映射,就不能对其进行修改。 唯一的方法是删除并重新创建索引。
在下面的示例中,我们手动创建了各种禁用动态映射的映射。
PUT /flight/_mapping
{
"dynamic": false,
"properties": {
"Rcvr": {
"type": "integer"
},
"Icao": {
"type": "text"
},
...
"location": {
"type": "geo_point"
}
}
}
复制代码
如果你更新了映射,请在禁用动态映射的情况下发出以下查询来更新 ElasticSearch,
POST /flight/_update_by_query?conflicts_proceed
复制代码
在这部分,我重点介绍了如何使用 ElasticSearch 的常用功能。
在下一一部分中,我们将学习如何在将 json 文件转换为 ElasticSearch 的批量 API 所需的格式之后,以及通过使用 JSON 库解析 json 文件,并将批处理 json 文件导入到 ElasticSearch 中。
评论