ElasticSearch 更新语法
685 字大约 2 分钟2024年12月4日
覆盖更新
你可以使用 _update
API 来更新单个文档。这种方法适用于需要覆盖整个文档的情况。
POST /my_index/_update/1
{
"doc": {
"title": "Updated Title",
"content": "Updated content."
}
}
部分更新
有时候,你只需要更新文档的某些字段,而不是整个文档。ElasticSearch 支持部分更新,只更新指定的字段。
示例:
POST /my_index/_update/1
{
"doc": {
"content": "Updated content."
}
}
在这个示例中,只有 content
字段被更新,而文档的其他字段保持不变。
脚本更新
你还可以使用脚本来更新文档。这种方法特别适用于需要对现有字段进行运算或条件更新的情况。
示例:
POST /my_index/_update/1
{
"script": {
"source": "ctx._source.view_count += params.count",
"lang": "painless",
"params": {
"count": 1
}
}
}
批量更新
当你需要一次性更新多个文档时,可以使用 _bulk
API 来进行批量更新。这种方法可以显著提高性能。
示例:
POST /_bulk
{ "update": { "_id": "1", "_index": "my_index" } }
{ "doc": { "content": "Bulk updated content." } }
{ "update": { "_id": "2", "_index": "my_index" } }
{ "doc": { "content": "Another bulk updated content." } }
更新嵌套字段
在 Elasticsearch 中,更新嵌套字段有时会比较复杂,因为嵌套对象本质上是独立的文档。更新嵌套字段通常需要使用脚本更新 (script update
)。
假设我们有一个包含订单信息的索引,每个订单包含嵌套的产品列表。现在,假设我们要更新 order_id
为 1001
的订单中的产品 Laptop
的价格。我们可以使用以下脚本更新来实现:
POST /orders/_update/1
{
"script": {
"source": """
for (int i = 0; i < ctx._source.products.size(); i++) {
if (ctx._source.products[i].name == params.product_name) {
ctx._source.products[i].price = params.new_price;
}
}
""",
"lang": "painless",
"params": {
"product_name": "Laptop",
"new_price": 1300
}
}
}
注意事项
- 并发控制: 当多个客户端同时更新同一个文档时,可能会发生冲突。可以使用
_version
或_seq_no
和_primary_term
来实现并发控制。 - 性能优化: 批量更新可以提高性能,但要注意合理的批量大小,以避免内存溢出。
- 脚本安全: 使用脚本更新时,要确保脚本的安全性,以防止恶意代码执行。