如何将多个运算符用于MongoDB聚合管道?

时间:2015-07-03 15:55:34

标签: mongodb aggregation-framework

我有一个包含此模式中文档的集合(是的,我知道这是无模式的世界,但是):

{
  name: "Real Colicos",
  fee: 123,
  creator: {},
  participants: [{},{}]
}

所以,我需要一个查询,我可以获得按参与者排序的第一组。当然我可以有一个participantCount属性,并使用$inc在更新时递增它,但我觉得这是一种天真的方法。这个聚合或地图是否会减少领域?

修改。解决方案是使用aggregate

docs我可以接受这个:

  db.groups.aggregate(
    [
      {
        $project: {
          name: 1,
          participantsCount: {$size: "$participants"}
        }
      }
    ])

此作品。现在我想知道,我如何对搜索进行分页,按参与者排序并仅包含一些文档属性?

我试过了:

  db.groups.aggregate(
    [
      {

        $project: {
          name: 1,
          participantsCount: {$size: "$participants"}
        },
        $skip: 10,
        $limit: 5,
        $sort: {participantsCount: -1},
        $match: {isPrivate: false}

      }
    ],
    function (err, results) {
      console.log(results);
    }
  );

但结果会抛出undefined

此外:

  db.groups.aggregate(
    [
      {

        $project: {
          name: 1,
          participantsCount: {$size: "$participants"}
        },
        {$skip: 10},
        {$limit: 5},
        {$sort: {participantsCount: -1}},
        {$match: {isPrivate: false}}

      }
    ],
    function (err, results) {
      console.log(results);
    }
  );

这是一个空数组。

甚至:

db.groups.aggregate(
    [
      {$project: {name: 1, isPrivate: 1, participantsCount: {$size: "$participants"}}},
      {$match: {isPrivate: false}},
      {$skip: 10},
      {$limit: 5},
      {$sort: {participantsCount: -1}}
    ],
    function (err, results) {
      console.log(results);
    }
  );

这也会抛出一个空数组。

2 个答案:

答案 0 :(得分:2)

我可以看到两个直接的问题:

  1. 这些阶段没有正确流水线化。它们目前都是一个对象的一部分,但应该在数组中显示为单独的文档:
  2.     db.groups.aggregate(
            [
              {$project: {name: 1, participantsCount: {$size: "$participants"}}},
              {$skip: 10},
              {$limit: 5},
              {$sort: {participantsCount: -1}},
              {$match: {isPrivate: false}}
            ],
            function (err, results) {
              console.log(results);
            }
          );
    
    1. 由于isPrivate在第一个$项目中被删除,因此没有任何内容会传递最后一个$ match。您可能需要在$ project中包含该字段。

答案 1 :(得分:1)

答案:聚合可以是管道。

来自docs:

  

聚合管道是基于数据处理管道概念建模的数据聚合框架。文档进入多阶段管道,将文档转换为聚合结果。

     

如果您的聚合操作仅需要集合中的一部分数据,请使用$ match,$ limit和$ skip阶段来限制在管道开头输入的文档。

所以这意味着处理一个管道以获得想要的结果。正如第二段建议的那样, 管道处理中的顺序事项

这就是它的样子:

collection.aggregate(
    [
      {$match: {isPrivate: false}},
      {$skip: 0},
      {$limit: 2},
      {$project: {name: 1, participantsCount: {$size: "$participants"}}},
      {$sort: {participantsCount: -1}}
    ]
  );