批量操作
使用批量文档 API 在单个请求中同时创建和更新多个文档。 基本操作类似于创建或更新单个文档、 除了批处理文档结构和信息。
创建新文档时,文档 ID 是可选项。 更新现有文件、 您必须提供文件 ID、 修订信息、 和新文档值。
批量操作的一个特例是 _bulk_get
端点。
批量申请结构
对于插入和更新,请求中 JSON 文档的基本结构包含以下字段:
字段 | 描述 | Type | 可选 |
---|---|---|---|
docs |
文件对象列表 | 对象的数组 | 否 |
最好不要使用 new_edits
字段。 默认情况下,如果存在冲突,文档更新将失败并向客户端返回错误信息。 不过,该选项在应用文档修订时不会检查冲突,因此很容易意外导致许多冲突。
Each docs
array object has the following structure:
字段 | 描述 | Type | 可选 |
---|---|---|---|
_id |
文档标识 | 字符串 | 仅适用于新文件。 否则,它就是强制性的。 |
_rev |
文档修订版 | 字符串 | 必须用于更新和删除,不用于新文件。 |
_deleted |
确定是否必须删除文件。 | 布尔值 | (可选)默认值为 false 。 |
回顾一下,对于分区数据库,_id
字段是由 分区键部分和文档键部分组成。
请参阅使用 HTTP 创建、更新或删除多个文档的示例:
POST /$DATABASE/_bulk_docs HTTP/1.1
Content-Type: application/json
查看使用命令行创建、更新或删除多个文档的示例:
curl -H "Authorization: Bearer $API_BEARER_TOKEN" -X POST "$SERVICE_URL/events/_bulk_docs" -H "Content-Type: application/json" --data '{ "docs": [ { "_id": "0007241142412418284", "type": "event", "userid": "abc123", "eventType": "addedToBasket", "productId": "1000042", "date": "2019-01-28T10:44:22.000Z" }, { "_id": "0008001142412418285", "type": "event", "userid": "def456", "eventType": "addedToBasket", "productId": "1000043", "date": "2019-01-28T12:30:00.000Z" } ], "new_edits": true }'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.BulkDocs;
import com.ibm.cloud.cloudant.v1.model.Document;
import com.ibm.cloud.cloudant.v1.model.DocumentResult;
import com.ibm.cloud.cloudant.v1.model.PostBulkDocsOptions;
import java.util.Arrays;
import java.util.List;
Cloudant service = Cloudant.newInstance();
Document eventDoc1 = new Document();
eventDoc1.setId("0007241142412418284");
eventDoc1.put("type", "event");
eventDoc1.put("userid", "abc123");
eventDoc1.put("eventType", "addedToBasket");
eventDoc1.put("productId", "1000042");
eventDoc1.put("date", "2019-01-28T10:44:22.000Z");
Document eventDoc2 = new Document();
eventDoc2.setId("0007241142412418285");
eventDoc2.put("type", "event");
eventDoc2.put("userid", "abc234");
eventDoc2.put("eventType", "addedToBasket");
eventDoc2.put("productId", "1000050");
eventDoc2.put("date", "2019-01-28T10:44:22.000Z");
BulkDocs bulkDocs = new BulkDocs.Builder()
.docs(Arrays.asList(eventDoc1, eventDoc2))
.build();
PostBulkDocsOptions bulkDocsOptions = new PostBulkDocsOptions.Builder()
.db("events")
.bulkDocs(bulkDocs)
.build();
List<DocumentResult> response =
service.postBulkDocs(bulkDocsOptions).execute()
.getResult();
System.out.println(response);
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
const eventDoc1 = {
_id: '0007241142412418284',
type: 'event',
userid: 'abc123',
eventType:'addedToBasket',
productId: '1000042',
date: '2019-01-28T10:44:22.000Z'
}
const eventDoc2 = {
_id: '0007241142412418285',
type: 'event',
userid: 'abc234',
eventType: 'addedToBasket',
productId: '1000050',
date: '2019-01-25T20:00:00.000Z'
}
const bulkDocs = { docs: [eventDoc1, eventDoc2] }
service.postBulkDocs({
db: 'events',
bulkDocs: bulkDocs
}).then(response => {
console.log(response.result);
});
from ibmcloudant.cloudant_v1 import Document, CloudantV1, BulkDocs
service = CloudantV1.new_instance()
event_doc_1 = Document(
id="0007241142412418284",
type="event",
userid="abc123",
eventType="addedToBasket",
productId="1000042",
date="2019-01-28T10:44:22.000Z"
)
event_doc_2 = Document(
id="0007241142412418285",
type="event",
userid="abc234",
eventType="addedToBasket",
productId="1000050",
date="2019-01-25T20:00:00.000Z"
)
bulk_docs = BulkDocs(docs=[event_doc_1, event_doc_2])
response = service.post_bulk_docs(
db='events',
bulk_docs=bulk_docs
).get_result()
print(response)
eventDoc1 := cloudantv1.Document{
ID: core.StringPtr("0007241142412418284"),
}
eventDoc1.SetProperty("type", "event")
eventDoc1.SetProperty("userid", "abc123")
eventDoc1.SetProperty("eventType", "addedToBasket")
eventDoc1.SetProperty("productId", "1000042")
eventDoc1.SetProperty("date", "2019-01-28T10:44:22.000Z")
eventDoc2 := cloudantv1.Document{
ID: core.StringPtr("0007241142412418285"),
}
eventDoc2.SetProperty("type", "event")
eventDoc2.SetProperty("userid", "abc234")
eventDoc2.SetProperty("eventType", "addedToBasket")
eventDoc2.SetProperty("productId", "1000050")
eventDoc2.SetProperty("date", "2019-01-25T20:00:00.000Z")
postBulkDocsOptions := service.NewPostBulkDocsOptions(
"events",
)
bulkDocs, err := service.NewBulkDocs(
[]cloudantv1.Document{
eventDoc1,
eventDoc2,
},
)
if err != nil {
panic(err)
}
postBulkDocsOptions.SetBulkDocs(bulkDocs)
documentResult, response, err := service.PostBulkDocs(postBulkDocsOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(documentResult, "", " ")
fmt.Println(string(b))
前面的围棋示例需要以下导入块:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
"github.com/IBM/go-sdk-core/v5/core"
)
所有 Go 示例都要求 service
对象初始化。 有关更多信息,请参阅 API 文档中的 "身份验证 "部分 的示例。
请参阅一个 JSON 示例,其中描述了在一个批量请求中更新、创建和删除三个文档的情况:
[
{
"id": "0007241142412418284",
"ok": true,
"rev": "1-5005d65514fe9e90f8eccf174af5dd64"
},
{
"id": "0008001142412418285",
"ok": true,
"rev": "1-2d7810b054babeda4812b3924428d6d6"
}
]
批量请求响应
收到的 HTTP 状态代码表示请求是完全成功还是部分成功。 在响应正文中 你会得到一个数组,其中包含请求中每个文档的详细信息。
代码 | 描述 |
---|---|
201 |
请求确实成功了,但这并不意味着所有文件都更新了。 检查响应正文,确定每项请求更改的状态,并 解决任何问题。 |
202 |
至少有一份文件不符合写入 定额组。 |
查看批量请求响应示例:
[
{
"ok":true,
"id":"96f898f0-f6ff-4a9b-aac4-503992f31b01",
"rev":"1-54dd23d6a630d0d75c2c5d4ef894454e"
},
{
"ok":true,
"id":"5a049246-179f-42ad-87ac-8f080426c17c",
"rev":"1-0cde94a828df5cdc0943a10f3f36e7e5"
},
{
"ok":true,
"id":"d1f61e66-7708-4da6-aa05-7cbc33b44b7e",
"rev":"1-a2b6e5dac4e0447e7049c8c540b309d6"
}
]
批量插入文件
要在数据库中批量插入文档,需要提供一个包含要添加到数据库的文档数组的 JSON 结构、 需要提供一个 JSON 结构,其中包含要添加到数据库的文档数组。 您可以为每个文档包含一个文档 ID、 或允许自动生成文档 ID。
请参阅批量插入三个文档的 JSON 示例:
{
"docs": [
{
"name": "Nicholas",
"age": 45,
"gender": "male",
"_id": "96f898f0-f6ff-4a9b-aac4-503992f31b01",
"_attachments": {
}
},
{
"name": "Taylor",
"age": 50,
"gender": "male",
"_id": "5a049246-179f-42ad-87ac-8f080426c17c",
"_attachments": {
}
},
{
"name": "Owen",
"age": 51,
"gender": "male",
"_id": "d1f61e66-7708-4da6-aa05-7cbc33b44b7e",
"_attachments": {
}
}
]
}
批量插入成功后的返回代码为 201
。 返回结构的内容表示成功 或其他信息。
请参阅成功批量插入三个文件后的响应标头示例:
201 Created
Cache-Control: must-revalidate
Content-Length: 269
Content-Type: application/json
Date: Mon, 04 Mar 2013 14:06:20 GMT
server: CouchDB/1.0.2 (Erlang OTP/R14B)
x-couch-request-id: e8ff64d5
返回的 JSON 包含创建的文档列表、 包括修订版和 ID 值。
返回的 JSON 内容和结构取决于批量更新所使用的事务语义。 更多信息、 请参阅 批量文档事务语义。
批量更新文档时出现的冲突和验证错误必须单独处理。 更多信息、 请参阅 批量文档验证和冲突错误。
请参阅成功批量插入两个文件后的响应内容示例:
[
{
"ok": true,
"id": "id1",
"rev": "2-402c81fee7ae6e723ff08bb166703a50"
},
{
"id": "id2",
"error": "conflict",
"reason": "Document update conflict."
}
]
批量更新文件
文档批量更新过程与插入过程类似、 不同的是,您必须在批量更新 JSON 字符串中为每个文档指定文档 ID 和当前修订版。
请参阅使用 HTTP 进行批量更新的示例:
POST /$DATABASE/_bulk_docs HTTP/1.1
Accept: application/json
请参阅使用命令行进行批量更新的示例:
curl -H "Authorization: Bearer $API_BEARER_TOKEN" -X POST "$SERVICE_URL/events/_bulk_docs" -H "Content-Type: application/json" --data '{ "docs": [ { "_id": "0007241142412418284", "type": "event", "userid": "abc123", "eventType": "addedToBasket", "productId": "1000042", "date": "2019-01-28T10:44:22.000Z" }, { "_id": "0008001142412418285", "type": "event", "userid": "def456", "eventType": "addedToBasket", "productId": "1000043", "date": "2019-01-28T12:30:00.000Z" } ], "new_edits": true }'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.BulkDocs;
import com.ibm.cloud.cloudant.v1.model.Document;
import com.ibm.cloud.cloudant.v1.model.DocumentResult;
import com.ibm.cloud.cloudant.v1.model.PostBulkDocsOptions;
import java.util.Arrays;
import java.util.List;
Cloudant service = Cloudant.newInstance();
Document eventDoc1 = new Document();
eventDoc1.setId("0007241142412418284");
eventDoc1.put("type", "event");
eventDoc1.put("userid", "abc123");
eventDoc1.put("eventType", "addedToBasket");
eventDoc1.put("productId", "1000042");
eventDoc1.put("date", "2019-01-28T10:44:22.000Z");
Document eventDoc2 = new Document();
eventDoc2.setId("0007241142412418285");
eventDoc2.put("type", "event");
eventDoc2.put("userid", "abc234");
eventDoc2.put("eventType", "addedToBasket");
eventDoc2.put("productId", "1000050");
eventDoc2.put("date", "2019-01-28T10:44:22.000Z");
BulkDocs bulkDocs = new BulkDocs.Builder()
.docs(Arrays.asList(eventDoc1, eventDoc2))
.build();
PostBulkDocsOptions bulkDocsOptions = new PostBulkDocsOptions.Builder()
.db("events")
.bulkDocs(bulkDocs)
.build();
List<DocumentResult> response =
service.postBulkDocs(bulkDocsOptions).execute()
.getResult();
System.out.println(response);
from ibmcloudant.cloudant_v1 import Document, CloudantV1, BulkDocs
service = CloudantV1.new_instance()
event_doc_1 = Document(
id="0007241142412418284",
type="event",
userid="abc123",
eventType="addedToBasket",
productId="1000042",
date="2019-01-28T10:44:22.000Z"
)
event_doc_2 = Document(
id="0007241142412418285",
type="event",
userid="abc234",
eventType="addedToBasket",
productId="1000050",
date="2019-01-25T20:00:00.000Z"
)
bulk_docs = BulkDocs(docs=[event_doc_1, event_doc_2])
response = service.post_bulk_docs(
db='events',
bulk_docs=bulk_docs
).get_result()
print(response)
eventDoc1 := cloudantv1.Document{
ID: core.StringPtr("0007241142412418284"),
}
eventDoc1.SetProperty("type", "event")
eventDoc1.SetProperty("userid", "abc123")
eventDoc1.SetProperty("eventType", "addedToBasket")
eventDoc1.SetProperty("productId", "1000042")
eventDoc1.SetProperty("date", "2019-01-28T10:44:22.000Z")
eventDoc2 := cloudantv1.Document{
ID: core.StringPtr("0007241142412418285"),
}
eventDoc2.SetProperty("type", "event")
eventDoc2.SetProperty("userid", "abc234")
eventDoc2.SetProperty("eventType", "addedToBasket")
eventDoc2.SetProperty("productId", "1000050")
eventDoc2.SetProperty("date", "2019-01-25T20:00:00.000Z")
postBulkDocsOptions := service.NewPostBulkDocsOptions(
"events",
)
bulkDocs, err := service.NewBulkDocs(
[]cloudantv1.Document{
eventDoc1,
eventDoc2,
},
)
if err != nil {
panic(err)
}
postBulkDocsOptions.SetBulkDocs(bulkDocs)
documentResult, response, err := service.PostBulkDocs(postBulkDocsOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(documentResult, "", " ")
fmt.Println(string(b))
const { CloudantV1 } = require('@ibm-cloud/cloudant');
const service = CloudantV1.newInstance({});
const eventDoc1 = {
_id: '0007241142412418284',
type: 'event',
userid: 'abc123',
eventType:'addedToBasket',
productId: '1000042',
date: '2019-01-28T10:44:22.000Z'
}
const eventDoc2 = {
_id: '0007241142412418285',
type: 'event',
userid: 'abc234',
eventType: 'addedToBasket',
productId: '1000050',
date: '2019-01-25T20:00:00.000Z'
}
const bulkDocs = { docs: [eventDoc1, eventDoc2] };
service.postBulkDocs({
db: 'events',
bulkDocs: bulkDocs
}).then(response => {
console.log(response.result);
});
前面的围棋示例需要以下导入块:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
"github.com/IBM/go-sdk-core/v5/core"
)
所有 Go 示例都要求 service
对象初始化。 有关更多信息,请参阅 API 文档中的 "身份验证 "部分 的示例。
请参阅请求批量更新文件的 JSON 结构示例:
{
"docs": [
{
"name": "Nicholas",
"age": 45,
"gender": "female",
"_id": "96f898f0-f6ff-4a9b-aac4-503992f31b01",
"_attachments": {
},
"_rev": "1-54dd23d6a630d0d75c2c5d4ef894454e"
},
{
"name": "Taylor",
"age": 50,
"gender": "female",
"_id": "5a049246-179f-42ad-87ac-8f080426c17c",
"_attachments": {
},
"_rev": "1-0cde94a828df5cdc0943a10f3f36e7e5"
},
{
"name": "Owen",
"age": 51,
"gender": "female",
"_id": "d1f61e66-7708-4da6-aa05-7cbc33b44b7e",
"_attachments": {
},
"_rev": "1-a2b6e5dac4e0447e7049c8c540b309d6"
}
]
}
返回的 JSON 结构汇总了更新的文档、 新版本和 ID 信息。
请参阅批量更新后返回的 JSON 结构示例:
[
{
"ok":true,
"id":"96f898f0-f6ff-4a9b-aac4-503992f31b01",
"rev":"2-ff7b85665c4c297838963c80ecf481a3"
},
{
"ok":true,
"id":"5a049246-179f-42ad-87ac-8f080426c17c",
"rev":"2-9d5401898196997853b5ac4163857a29"
},
{
"ok":true,
"id":"d1f61e66-7708-4da6-aa05-7cbc33b44b7e",
"rev":"2-cbdef49ef3ddc127eff86350844a6108"
}
]
批量删除文件
要从数据库中删除文档,必须用 "_deleted": true
字段提供特定文档的 ID 和修订版。
请参阅请求批量删除两个文档的 JSON 结构示例:
返回的 JSON 结构汇总了已删除的文档、 以及新版本和 ID 信息。
{
"docs": [
{
"_id": "person34567",
"_deleted": true,
"_rev": "2-54dd23d6a630d0d75c2c5d4ef894454e"
},
{
"_id": "person568",
"_deleted": true,
"_rev": "3-8a245604ee5e829d7fbd1b456aed01ac"
}
]
}
请参阅批量删除后返回的 JSON 结构示例:
[
{
"ok": true,
"id": "person34567",
"rev": "3-674ccbb6ec6fe6d7ba0fb30a5eecf664"
},
{
"ok": true,
"id": "person568",
"rev": "4-c6067e21e97557f54d29282461843037"
}
]
批量文件交易语义
如果您的请求收到 202
响应、 唯一可以确定的是,部分文件任务已完全处理完毕。 响应体包含在处理过程中成功插入或更新的文件列表。
文件更新成功的标志是文件出现了一个新的 _rev
参数、 表示成功创建了新的文档修订版。
如果文档更新失败、 则会得到该文档的 error
类型的 conflict
。 在这种情况下 没有创建新版本。 您必须再次提交文件更新、 使用相同的修订标签、 以重试文件更新。
查看带错误的批量更新响应示例:
[
{
"id" : "FishStew",
"error" : "conflict",
"reason" : "Document update conflict."
},
{
"id" : "LambStew",
"error" : "conflict",
"reason" : "Document update conflict."
},
{
"id" : "7f7638c86173eb440b8890839ff35433",
"error" : "conflict",
"reason" : "Document update conflict."
}
]
批量文件验证和冲突错误
该 _bulk_docs
操作返回的 JSON 包含一个 JSON 结构数组、 数组。 必须检查返回的 JSON 结构 以确保原始请求中提交的所有文档都已成功添加到数据库中。
返回信息的结构如下表所示:
字段 | 描述 | Type |
---|---|---|
docs |
文件对象列表 | 对象的数组 |
Each docs
array object has the following structure:
字段 | 描述 | Type |
---|---|---|
id |
文档标识 | 字符串 |
error |
错误类型 | 字符串 |
reason |
带扩展原因的错误字符串 | 字符串 |
当文档(或文档修订版)因错误而无法正确提交到数据库时、 必须检查 error
字段,以确定错误类型和处理方法。 错误为 conflict
或 forbidden
。
conflict
提交的文件存在冲突。 如果使用默认批量事务模式、 则不会创建新版本。 您必须重新向数据库提交文件。
使用批量文档界面解决冲突的方法与 冲突 文档中概述的解决程序相同。
forbidden
此错误类型的条目表示在提交过程中应用于文档的验证例程 返回错误。
请参阅JavaScript示例,了解如何在验证功能中产生 forbidden
错误:
throw({forbidden: 'invalid recipe ingredient'});
查看验证函数的错误信息示例:
{
"id" : "7f7638c86173eb440b8890839ff35433",
"error" : "forbidden",
"reason" : "invalid recipe ingredient"
}
The _bulk_get
endpoint
您可能需要访问多个文件的所有可用信息。 The _bulk_get
endpoint is similar to the _all_docs
endpoint, but returns information about the requested documents only.
与 _bulk_docs
端点一样、 请求中提供的 JSON 文档包含一个数组,用于标识所有相关文档。
请参阅使用 HTTP 批量 GET
文档信息的示例:
POST /$DATABASE/_bulk_get HTTP/1.1
Accept: application/json
请参阅使用命令行运行批量 GET
示例:
curl -H "Authorization: Bearer $API_BEARER_TOKEN" -X POST "$SERVICE_URL/orders/_bulk_get" -H "Content-Type: application/json" --data '{
"docs": [
{
"id": "order00067",
"rev": "3-917fa2381192822767f010b95b45325b"
},
{
"id": "order00067"
"rev": "4-a5be949eeb7296747cc271766e9a498b"
}
],
}'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.BulkGetQueryDocument;
import com.ibm.cloud.cloudant.v1.model.BulkGetResult;
import com.ibm.cloud.cloudant.v1.model.PostBulkGetOptions;
import java.util.ArrayList;
import java.util.List;
Cloudant service = Cloudant.newInstance();
String docId = "order00067";
List<BulkGetQueryDocument> bulkGetDocs = new ArrayList<>();
bulkGetDocs.add(
new BulkGetQueryDocument.Builder()
.id(docId)
.rev("3-917fa2381192822767f010b95b45325b")
.build());
bulkGetDocs.add(
new BulkGetQueryDocument.Builder()
.id(docId)
.rev("4-a5be949eeb7296747cc271766e9a498b")
.build());
PostBulkGetOptions bulkGetOptions = new PostBulkGetOptions.Builder()
.db("orders")
.docs(bulkGetDocs)
.build();
BulkGetResult response =
service.postBulkGet(bulkGetOptions).execute()
.getResult();
System.out.println(response);
from ibmcloudant.cloudant_v1 import BulkGetQueryDocument, CloudantV1
service = CloudantV1.new_instance()
doc_id = 'order00067'
bulk_get_doc_1 = BulkGetQueryDocument(
id=doc_id,
rev='3-917fa2381192822767f010b95b45325b')
bulk_get_doc_2 = BulkGetQueryDocument(
id=doc_id,
rev='4-a5be949eeb7296747cc271766e9a498b')
response = service.post_bulk_get(
db='orders',
docs=[bulk_get_doc_1, bulk_get_doc_2],
).get_result()
print(response)
docID := "order00067"
bulkGetDocs := []cloudantv1.BulkGetQueryDocument{
{
ID: &docID,
Rev: core.StringPtr("3-917fa2381192822767f010b95b45325b"),
},
{
ID: &docID,
Rev: core.StringPtr("4-a5be949eeb7296747cc271766e9a498b"),
},
}
postBulkGetOptions := service.NewPostBulkGetOptions(
"orders",
bulkGetDocs,
)
bulkGetResult, response, err := service.PostBulkGet(postBulkGetOptions)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(bulkGetResult, "", " ")
fmt.Println(string(b))
const service = CloudantV1.newInstance({});
const docId = 'order00067';
const bulkGetDoc1 = {
id: docId,
rev: '3-917fa2381192822767f010b95b45325b'
};
const bulkGetDoc2 = {
id: docId,
rev: '4-a5be949eeb7296747cc271766e9a498b'
};
const bulkGetDocs = [bulkGetDoc1, bulkGetDoc2];
const postBulkGetParams = {
db: 'orders',
docs: bulkGetDocs,
};
service.postBulkGet(postBulkGetParams)
.then(response => {
console.log(response.result);
});
前面的围棋示例需要以下导入块:
import (
"encoding/json"
"fmt"
"github.com/IBM/cloudant-go-sdk/cloudantv1"
"github.com/IBM/go-sdk-core/v5/core"
)
所有 Go 示例都要求 service
对象初始化。 有关更多信息,请参阅 API 文档中的 "身份验证 "部分 的示例。
请参阅使用 POST
到 _bulk_get
端点的 JSON 对象示例:
{
"docs": [
{
"id": "doc1"
},
{
"id": "doc3"
}
]
}
请参阅批量获取后返回的 JSON 结构示例:
{
"results": [
{
"id": "doc01",
"docs": [
{
"ok": {
"_id": "doc01",
"_rev": "1-f3751e2db1d92e13b0baa6bdeb874c8c",
"simplekey": "somedata"
}
}
]
},
{
"id": "doc03",
"docs": [
{
"ok": {
"_id": "doc03",
"_rev": "2-d4fc04ef748edf305a8c0ed347f269c4",
"simplekey": "somemoredata"
}
}
]
}
]
}