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 /flightGET /_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/logsGET /_cat/indices?v health status index uuid pri rep docs.count docs.deleted store.size pri.store.sizeyellow 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 中。
评论