一次调用可以从 CouchDB 检索多少文档
How many documents can be retrieved from CouchDB in a single call
CouchDB 数据库中存储了 500,000 个文档。客户端应用程序需要检索所有文档以处理到另一个系统中。是否有推荐的方法来检索所有内容?我知道有使用“limit”和“skip”参数的分页支持。看起来可以进行调用以获取总文档,然后使用循环调用 CouchDB 动态更新“限制”和“跳过”值。是否有其他方法来检索所有内容?
除了复制,我认为不是。当然,这实际上取决于 OP 中未给出的细节。 200kb 文档中的 500k 可能不是 带宽问题,但 100kb 文档中的 500k 可能 是一个考虑因素。
有很多方法可以解决这个问题,由于有很多细节没有给出,大多数人所能做的就是提供一个通用的方法,我将在这里做。
实质是/{db}/_all_docs与start_key
、limit
和skip
的组合使用。
初始状态应该是
start_key = null
因为 null 在 CouchDB 中是第一个 Views Collation
limit = ?
任意,因为它取决于平均文档大小、带宽、处理能力等。
skip = 0
一开始就不想跳过任何东西
一般的解决办法是根据上次回复调整start_key
和limit
请注意 skip
可以 be very inefficient。在此解决方案中,skip
是 0 或 1,这很好。
每个后续状态都取决于先前的响应:
start_key = last rows doc key
不知道下一个键是什么,对吧?
skip = 1
所以响应不包括最后一个响应文档
换句话说,后续请求是说“给我下一组文档,从收到的最后一个文档密钥开始”。
这是一个基于 nano 的脚本,它提供了一个骨架,可以在上面扔肉。它是幼稚的,因为它建议 URL 凭据并且为了清楚起见没有错误处理。
const nano = require("nano")("http://{uid:pwd@address:port");
const db = nano.db.use("{your db name}");
const echo = (json) => console.log(JSON.stringify(json, undefined, 2));
const processRows = (rows) => {
echo(rows);
};
(async () => {
let start_key = null;
let limit = 2; // whatever
let skip = 0;
let response;
let more = false;
do {
if (response) {
// next query is based on the last query.
start_key = response.rows.pop().key;
skip = 1;
}
response = await db.list({ start_key, limit, skip });
processRows(response.rows);
more = response.rows.length === limit;
} while (more);
console.info("Procesing completed.");
})();
最后的话,这也会 return _design_docs - 可能想过滤掉那些。
更新
我忽略了添加实际答案:默认是 return all 行,如 CouchDB 文档部分 1.5.4.4. Using Limits and Skipping Rows 中所述,所以这取决于调用者。
CouchDB 数据库中存储了 500,000 个文档。客户端应用程序需要检索所有文档以处理到另一个系统中。是否有推荐的方法来检索所有内容?我知道有使用“limit”和“skip”参数的分页支持。看起来可以进行调用以获取总文档,然后使用循环调用 CouchDB 动态更新“限制”和“跳过”值。是否有其他方法来检索所有内容?
除了复制,我认为不是。当然,这实际上取决于 OP 中未给出的细节。 200kb 文档中的 500k 可能不是 带宽问题,但 100kb 文档中的 500k 可能 是一个考虑因素。
有很多方法可以解决这个问题,由于有很多细节没有给出,大多数人所能做的就是提供一个通用的方法,我将在这里做。
实质是/{db}/_all_docs与start_key
、limit
和skip
的组合使用。
初始状态应该是
start_key = null
因为 null 在 CouchDB 中是第一个 Views Collationlimit = ?
任意,因为它取决于平均文档大小、带宽、处理能力等。skip = 0
一开始就不想跳过任何东西
一般的解决办法是根据上次回复调整start_key
和limit
请注意 skip
可以 be very inefficient。在此解决方案中,skip
是 0 或 1,这很好。
每个后续状态都取决于先前的响应:
start_key = last rows doc key
不知道下一个键是什么,对吧?skip = 1
所以响应不包括最后一个响应文档
换句话说,后续请求是说“给我下一组文档,从收到的最后一个文档密钥开始”。
这是一个基于 nano 的脚本,它提供了一个骨架,可以在上面扔肉。它是幼稚的,因为它建议 URL 凭据并且为了清楚起见没有错误处理。
const nano = require("nano")("http://{uid:pwd@address:port");
const db = nano.db.use("{your db name}");
const echo = (json) => console.log(JSON.stringify(json, undefined, 2));
const processRows = (rows) => {
echo(rows);
};
(async () => {
let start_key = null;
let limit = 2; // whatever
let skip = 0;
let response;
let more = false;
do {
if (response) {
// next query is based on the last query.
start_key = response.rows.pop().key;
skip = 1;
}
response = await db.list({ start_key, limit, skip });
processRows(response.rows);
more = response.rows.length === limit;
} while (more);
console.info("Procesing completed.");
})();
最后的话,这也会 return _design_docs - 可能想过滤掉那些。
更新
我忽略了添加实际答案:默认是 return all 行,如 CouchDB 文档部分 1.5.4.4. Using Limits and Skipping Rows 中所述,所以这取决于调用者。