mongodb聚合框架组+项目

时间:2013-03-08 02:40:36

标签: mongodb mongodb-query

我有以下问题:

此查询返回1个结果,这就是我想要的:

> db.items.aggregate([ {$group: { "_id": "$id", version: { $max: "$version" } } }])

{
"result" : [
    {
        "_id" : "b91e51e9-6317-4030-a9a6-e7f71d0f2161",
        "version" : 1.2000000000000002
    }
],
"ok" : 1
}

这个查询(我只是添加了投影,所以我以后可以查询整个文档)返回多个结果。我做错了什么?

> db.items.aggregate([ {$group: { "_id": "$id", version: { $max: "$version" } }, $project: { _id : 1 } }])

  {
"result" : [
    {
        "_id" : ObjectId("5139310a3899d457ee000003")
    },
    {
        "_id" : ObjectId("513931053899d457ee000002")
    },
    {
        "_id" : ObjectId("513930fd3899d457ee000001")
    }
],
"ok" : 1
}

3 个答案:

答案 0 :(得分:0)

找到了答案

1。首先,我需要获得所有_ids

db.items.aggregate( [ 
  { '$match': { 'owner.id': '9e748c81-0f71-4eda-a710-576314ef3fa' } },
  { '$group': { _id: '$item.id', dbid: { $max: "$_id" } } } 
]);

2。那我需要查询文件

db.items.find({ _id: { '$in': "IDs returned from aggregate" } });

看起来像这样:

db.items.find({ _id: { '$in': [ '1', '2', '3' ] } });

答案 1 :(得分:0)

我知道它已经很晚了,但仍在回答它以便其他人不必在其他地方寻找正确的答案

请参阅answer of Deka,这将完成您的工作。

答案 2 :(得分:0)

$project阶段并非所有累加器都可用。我们需要考虑在累积器方面我们可以在项目中做些什么,以及我们可以在小组中做些什么。我们来看看这个:


db.companies.aggregate([{
  $match: {
    funding_rounds: {
      $ne: []
    }
  }
}, {
  $unwind: "$funding_rounds"
}, {
  $sort: {
    "funding_rounds.funded_year": 1,
    "funding_rounds.funded_month": 1,
    "funding_rounds.funded_day": 1
  }
}, {
  $group: {
    _id: {
      company: "$name"
    },
    funding: {
      $push: {
        amount: "$funding_rounds.raised_amount",
        year: "$funding_rounds.funded_year"
      }
    }
  }
}, ]).pretty()

$group in MongoDB

我们在哪里检查funding_rounds是否为空。然后它unwind - 编辑到$sort以及后续阶段。我们将为每家公司查看funding_rounds数组的每个元素的一个文档。所以,我们要做的第一件事就是$sort基于:

  1. funding_rounds.funded_year
  2. funding_rounds.funded_month
  3. funding_rounds.funded_day
  4. 在公司名称的小组阶段,使用$push构建数组。 $push应该是指定为我们在组阶段中命名的字段的值的文档的一部分。我们可以推动任何有效的表达。在这种情况下,我们将文档推送到此数组,并且我们将其推送到的每个文档都被添加到我们正在累积的数组的末尾。在这种情况下,我们会推送从raised_amountfunded_year构建的文档。因此,$group阶段是一个包含_id的文档流,我们在其中指定公司名称。

    请注意,$push阶段$group可用,但$project阶段不可用。这是因为$group阶段旨在获取一系列文档并根据该文档流累积值。

    另一方面,

    $project一次只能处理一个文档。因此,我们可以计算项目阶段内单个文档中数组的平均值。但是做这样的事情,一次一个,我们看到文件和每个文件,它通过小组阶段推动一个新的价值,这是$project阶段的事情只是不打算做。对于那种类型的操作,我们希望使用$group

    让我们来看看另一个例子:

    
    db.companies.aggregate([{
      $match: {
        funding_rounds: {
          $exists: true,
          $ne: []
        }
      }
    }, {
      $unwind: "$funding_rounds"
    }, {
      $sort: {
        "funding_rounds.funded_year": 1,
        "funding_rounds.funded_month": 1,
        "funding_rounds.funded_day": 1
      }
    }, {
      $group: {
        _id: {
          company: "$name"
        },
        first_round: {
          $first: "$funding_rounds"
        },
        last_round: {
          $last: "$funding_rounds"
        },
        num_rounds: {
          $sum: 1
        },
        total_raised: {
          $sum: "$funding_rounds.raised_amount"
        }
      }
    }, {
      $project: {
        _id: 0,
        company: "$_id.company",
        first_round: {
          amount: "$first_round.raised_amount",
          article: "$first_round.source_url",
          year: "$first_round.funded_year"
        },
        last_round: {
          amount: "$last_round.raised_amount",
          article: "$last_round.source_url",
          year: "$last_round.funded_year"
        },
        num_rounds: 1,
        total_raised: 1,
      }
    }, {
      $sort: {
        total_raised: -1
      }
    }]).pretty()
    

    group vs project in MongoDB

    $group阶段,我们正在使用$first$last累加器。是的,我们再次看到与$push一样 - 我们无法在项目阶段使用$first$last。因为同样,项目阶段不是为了根据多个文档累积值而设计的。相反,它们被设计为一次一个地重塑文档。使用$sum运算符计算总轮数。值 1 只是计算通过该组的文档数量以及匹配或在给定_id值下分组的每个文档。这个项目可能看起来很复杂,但它只是让输出很漂亮。只是它包括前一个文档中的num_roundstotal_raised