一次调用可以从 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_docsstart_keylimitskip的组合使用。

初始状态应该是

  • start_key = null 因为 null 在 CouchDB 中是第一个 Views Collation
  • limit = ? 任意,因为它取决于平均文档大小、带宽、处理能力等。
  • skip = 0一开始就不想跳过任何东西

一般的解决办法是根据上次回复调整start_keylimit

请注意 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 中所述,所以这取决于调用者。