分页的mongodb聚合跳过限制计数

时间:2018-02-28 14:06:07

标签: mongodb pagination mongodb-query

我想对这个聚合数据应用分页(所有与第2和第3集匹配和投影的文档)。我试过多次 查询,我通过限制25但它只会获得20个文档,这个更改需要在此查询中进行分页

var pipeline = [{
        $match: query
    }, {
        $limit: limit
    }, {
        $skip: skip
    }, {
        $lookup: {
            from: "collection2",
            localField: "collection1Field",
            foreignField: "collection2Field",
            as: "combined1"
        }
    }, {
        "$unwind": "$combined1"
    }, {
        $lookup: {
            from: "collection3",
            localField: "collection1Field",
            foreignField: "collection3Field",
            as: "combined2"
        }
    }, {
        "$unwind": "$combined2"
    }, {
        $project: {
            "collection1Field1": 1,
            "collection1Field2": 1,
            "collection1Field3": 1,
            "collection2Field.field1": 1,
            "collection2Field.field2": 1,
            "collection3Field.field1": 1,
            "collection3Field.field2": 1,
        }
    }
];

2 个答案:

答案 0 :(得分:2)

我刚才有类似的问题。由于我运行了limit,然后skip,我在“第2页”上没有收到任何结果。

$skip的文档:

  

跳过传入舞台的指定数量的文档   并将剩余的文件传递给管道中的下一个阶段。

$limit的文档:

  

限制传递到下一阶段的文档数量   管道

这意味着如果您在limit之前运行skip,则限制返回的结果可能会被skip截断。

例如,如果limit为50且skip为50(例如第2页),则匹配将找到项目,将结果限制为50,然后跳过50,从而提供0结果之后进入任何阶段。

我不推荐在查询结束时运行$skip$limit,因为数据库将对将要跳过的大量数据进行管道操作/限制在最后。此外,如果超出限制(100MB - 请参阅底部),则可以使用的内存聚合数量有限,这将限制错误中的查询。如果超出此限制,可以选择启用磁盘,但是在不依赖磁盘的情况下优化代码的好方法是在输入任何$lookup$unwind步骤之前跳过+限制结果。

该规则的一个例外是$sort,如果$limit紧跟$limit(文档)后,该$sort智能足以使用$sort

  

$limit紧接在管道中的$sort之前时,var pipeline = [{ $match: query }, { $skip: skip }, { $limit: limit }, { $lookup: { from: "collection2", localField: "collection1Field", foreignField: "collection2Field", as: "combined1" } }, { "$unwind": "$combined1" }, { $lookup: { from: "collection3", localField: "collection1Field", foreignField: "collection3Field", as: "combined2" } }, { "$unwind": "$combined2" }, { $project: { "collection1Field1": 1, "collection1Field2": 1, "collection1Field3": 1, "collection2Field.field1": 1, "collection2Field.field2": 1, "collection3Field.field1": 1, "collection3Field.field2": 1, } }];   操作仅在进展时保持顶部 n 结果,其中 n   是指定的限制,MongoDB只需要存储 n 项   记忆。当 allowDiskUse true 时,此优化仍适用    n 项超出了聚合内存限制。

从您的代码中我建议以下(跳过然后限制):

$graphLookup

有关聚合管道限制的文档:

  

内存限制在版本2.6中已更改。

     

管道阶段的内存限制为100兆字节。如果一个阶段   超过此限制,MongoDB将产生错误。允许的   处理大型数据集时,请使用allowDiskUse选项启用   聚合管道阶段将数据写入临时文件。

     

在版本3.4中更改。

     

allowDiskUse: true阶段必须保持在100兆字节的内存限制内。   如果为aggregate()操作指定了$graphLookup,则   aggregate()阶段忽略该选项。如果还有其他阶段   allowDiskUse: true操作,<img src="www.image.com" width="35" height="35"/> 选项生效   这些其他阶段。

答案 1 :(得分:0)

您希望在获得结果后进行分页。

var pipeline = [{
        $match: query
    }, {
        $lookup: {
            from: "collection2",
            localField: "collection1Field",
            foreignField: "collection2Field",
            as: "combined1"
        }
    }, {
        "$unwind": "$combined1"
    }, {
        $lookup: {
            from: "collection3",
            localField: "collection1Field",
            foreignField: "collection3Field",
            as: "combined2"
        }
    }, {
        "$unwind": "$combined2"
    }, {
        $project: {
            "collection1Field1": 1,
            "collection1Field2": 1,
            "collection1Field3": 1,
            "collection2Field.field1": 1,
            "collection2Field.field2": 1,
            "collection3Field.field1": 1,
            "collection3Field.field2": 1,
        }
    }, {
        $limit: limit
    }, {
        $skip: skip
    }
];
相关问题