ElasticSearch基础数据管理-3-文档操作详解
1、简介
文档作为Elasticsearch的基本存储单元,文档是指存储在Elasticsearch索引中的JSON对象。
2、文档的基本操作
以下操作基于 Elasticsearch 7.x 及以上版本。
1、新增文档
新增文档的操作可以通过POST或PUT请求完成,具体取决于是否指定了文档的唯一性标识(即ID)。如果在创建数据时指定了唯一性标识,可以使用POST或PUT请求;如果没有指定唯一性标识,只能使用POST请求。
1.1 指定ID创建(PUT)
PUT /<index>/_doc/<_id> { "field1": "value1", "field2": "value2" } # 示例:创建商品文档 PUT /products/_doc/1001 { "name": "iPhone 15 Pro", "price": 8999, "category": "电子产品", "stock": 50, "tags": ["手机", "苹果", "旗舰"], "specs": { "color": "深空黑", "storage": "256GB" }, "created_at": "2024-12-01T10:30:00" } # 响应示例 { "_index": "products", "_id": "1001", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 0, "_primary_term": 1 }
1.2 自动生成ID创建(POST)
POST /products/_doc/ { "name": "MacBook Pro", "price": 12999 } # 响应包含自动生成的ID { "_id": "abc123def456" }
1.3 创建时指定操作类型
PUT /products/_create/1002 # 如果文档已存在则失败 { "name": "iPad" } # 或 PUT /products/_doc/1002?op_type=create
2、获取文档
2.1 获取单个文档
GET /products/_doc/1001 # 响应 { "_index": "products", "_id": "1001", "_version": 2, "_seq_no": 1, "_primary_term": 1, "found": true, "_source": { "name": "iPhone 15 Pro", "price": 8999, "category": "电子产品" } }
2.2 获取多个文档(mget)
GET /_mget { "docs": [ { "_index": "products", "_id": "1001" }, { "_index": "products", "_id": "1002" }, { "_index": "users", "_id": "user_001" } ] } # 或指定索引 GET /products/_mget { "ids": ["1001", "1002", "1003"] }
其他操作
# 2.3 只获取特定字段 GET /products/_doc/1001?_source=name,price # 2.4 排除特定字段 GET /products/_doc/1001?_source_exclude=tags,specs # 2.5 只获取_source部分 GET /products/_source/1001 # 2.6 检查文档是否存在 HEAD /products/_doc/1001 # 返回200存在,404不存在
2.3、根据搜索关键词查询文档
查询文档通常使用Query DSL(Domain Specific Language),这是一种基于JSON的语言,用于构建复杂的搜索查询。
GET /<index_name>/_search { "query": { # - 匹配所有文档 "match_all": {} # - 文本字段匹配 "match": { "<field_name>": "<query_string>" } # - 精确匹配(不分词) "term": { "<field_name>": { "value": "<exact_value>" } } # 范围查询 "range": { "<field_name>": { "gte": <lower_bound>, "lte": <upper_bound> } } } }
3、更新文档
3.1 全量替换(PUT)当前更新不存在字段也会被替换掉
PUT /products/_doc/1001 { "name": "iPhone 15 Pro Updated", "price": 8499, # 注意:未包含的字段会被删除! "category": "电子产品" }
3.2 部分更新(推荐)
POST /products/_update/1001 { "doc": { "price": 8199, "stock": 45, "new_field": "促销中" } }
3.3 使用脚本更新
POST /products/_update/1001 { "script": { "source": """ // 增加价格 ctx._source.price += 100; // 减少库存 if (ctx._source.containsKey('stock')) { ctx._source.stock -= params.sold; } // 添加标签 if (!ctx._source.tags.contains(params.newTag)) { ctx._source.tags.add(params.newTag); } // 设置更新时间 ctx._source.updated_at = params.now; """, "params": { "sold": 5, "newTag": "促销", "now": "2024-12-02T09:00:00" }, "lang": "painless" } }
3.4 条件更新(只有文档存在时才更新)
POST /<index_name>/_update_by_query { "query": { <!-- 定义更新文档的查询条件 --> }, "script": { "source": "ctx._source.field = 'new_value'", "lang": "painless" } }
在这个请求中,<index_name>是您要更新的索引名称,query部分定义了哪些文档需要被更新,script部分定义了如何更新这些文档的字段。
并发场景下更新文档如何保证线程安全?
在Elasticsearch 7.x及以后的版本中,_seq_no和_primary_term取代了旧版本的_version字段,用于控制文档的版本。_seq_no代表文档在特定分片中的序列号,而_primary_term代表文档所在主分片的任期编号。这两个字段共同构成了文档的唯一版本标识符,用于实现乐观锁机制,确保在高并发环境下文档的一致性和正确更新。
当在高并发环境下使用乐观锁机制修改文档时,要带上当前文档的_seq_no和_primary_term进行更新:
如果_seq_no和_primary_term不对,会抛出版本冲突异常。
POST /employee/_doc/1?if_seq_no=13&if_primary_term=1 { "name": "张三xxxx", "sex": 1, "age": 25 }
以前的使用版本号
POST /products/_update/1001?version=2&version_type=external { "doc": { "price": 7999 } }
更新时重试冲突(乐观锁)
POST /products/_update/1001?retry_on_conflict=3 { "doc": { "stock": 40 } }
4、 删除文档
4.1 删除单个文档
DELETE /products/_doc/1001 # 响应 { "_index": "products", "_id": "1001", "_version": 3, "result": "deleted", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 3, "_primary_term": 1 }
4.2 按条件删除文档
POST /products/_delete_by_query { "query": { "range": { "price": { "lt": 1000 } } } }
4.3 删除多个文档(使用 mdelete)
POST /products/_bulk { "delete": { "_id": "1001" } } { "delete": { "_id": "1002" } } # 4.4 删除所有文档(保留索引结构) POST /products/_delete_by_query { "query": { "match_all": {} } }
5、批量操作
批量新增文档可以通过_bulk API来实现。这个API允许您将多个索引、更新或删除操作组合成一个单一的请求,从而提高批量操作的效率。
Elasticsearch的_bulk API支持以下四种操作类型:
- Index: 用于创建新文档或替换已有文档。
- Create: 如果文档不存在则创建,如果文档已存在则返回错误。
- Update: 用于更新现有文档。
- Delete: 用于删除指定的文档。
# Bulk 操作格式:每行一个操作说明,下一行为数据(delete没有数据行) POST /_bulk { "index": { "_index": "products", "_id": "2001" } } { "name": "小米13", "price": 3999, "category": "手机" } { "delete": { "_index": "products", "_id": "1001" } } { "create": { "_index": "products", "_id": "2002" } } { "name": "华为Mate60", "price": 6999 } { "update": { "_index": "products", "_id": "2002" } } { "doc": { "stock": 30 } }

浙公网安备 33010602011771号