MongoDB如何对具有唯一值的项运行聚合查询

MongoDB如何对具有唯一值的项运行聚合查询,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有一个元数据集合,其中包含如下字段: { _id: "...", value: "somevalue1", filename: "foo" }, { _id: "...", value: "somevalue1", filename: "bar" }, { _id: "...", value: "somevalue1", filename: "foo" }, { _id: "...", value: "somevalue2", filename: "foo" }, 我当前获得了按文件名分组的

我有一个
元数据
集合,其中包含如下字段:

{ _id: "...", value: "somevalue1", filename: "foo" },
{ _id: "...", value: "somevalue1", filename: "bar" },
{ _id: "...", value: "somevalue1", filename: "foo" },
{ _id: "...", value: "somevalue2", filename: "foo" },
我当前获得了按文件名分组的计数,例如:

foo:3巴:1巴

但我真正想要的是,也要根据
值计算,而每个值只应该计算一次

因此,结果应该是:

foo:2巴:1巴

我当前的代码如下(其中有一些黑客使其与Meteor一起工作):

使用“两个”管道阶段。一个是获取唯一的组合字段,然后从每个结果中获取唯一的“filename”值。这是一个“管道”,因此在每个阶段向下一个阶段提供输入时,这样做没有错:

var管道=[
{“$组”:{
“_id”:{“value”:“$value”,“filename”:“$filename”}
}},
{“$组”:{
“\u id”:“$\u id.filename”,
“计数”:{“$sum”:1}
}}
];
这使得结果:

{u id:“foo”,“count”:2}
{u id:“bar”,“count”:1}
由于第一个
$group
将“somevalue1”和“foo”组合减少为一个唯一的条目

不确定为什么要将此前缀加上
数据
,因为您的示例没有反映该结构,但如果它不同,请在第一个管道阶段更改它

也不需要,因为如果字段不存在,
null
将是默认值。

使用“两个”管道阶段。一个是获取唯一的组合字段,然后从每个结果中获取唯一的“filename”值。这是一个“管道”,因此在每个阶段向下一个阶段提供输入时,这样做没有错:

var管道=[
{“$组”:{
“_id”:{“value”:“$value”,“filename”:“$filename”}
}},
{“$组”:{
“\u id”:“$\u id.filename”,
“计数”:{“$sum”:1}
}}
];
这使得结果:

{u id:“foo”,“count”:2}
{u id:“bar”,“count”:1}
由于第一个
$group
将“somevalue1”和“foo”组合减少为一个唯一的条目

不确定为什么要将此前缀加上
数据
,因为您的示例没有反映该结构,但如果它不同,请在第一个管道阶段更改它

也不需要,因为如果字段不存在,
null
将是默认值。

使用“两个”管道阶段。一个是获取唯一的组合字段,然后从每个结果中获取唯一的“filename”值。这是一个“管道”,因此在每个阶段向下一个阶段提供输入时,这样做没有错:

var管道=[
{“$组”:{
“_id”:{“value”:“$value”,“filename”:“$filename”}
}},
{“$组”:{
“\u id”:“$\u id.filename”,
“计数”:{“$sum”:1}
}}
];
这使得结果:

{u id:“foo”,“count”:2}
{u id:“bar”,“count”:1}
由于第一个
$group
将“somevalue1”和“foo”组合减少为一个唯一的条目

不确定为什么要将此前缀加上
数据
,因为您的示例没有反映该结构,但如果它不同,请在第一个管道阶段更改它

也不需要,因为如果字段不存在,
null
将是默认值。

使用“两个”管道阶段。一个是获取唯一的组合字段,然后从每个结果中获取唯一的“filename”值。这是一个“管道”,因此在每个阶段向下一个阶段提供输入时,这样做没有错:

var管道=[
{“$组”:{
“_id”:{“value”:“$value”,“filename”:“$filename”}
}},
{“$组”:{
“\u id”:“$\u id.filename”,
“计数”:{“$sum”:1}
}}
];
这使得结果:

{u id:“foo”,“count”:2}
{u id:“bar”,“count”:1}
由于第一个
$group
将“somevalue1”和“foo”组合减少为一个唯一的条目

不确定为什么要将此前缀加上
数据
,因为您的示例没有反映该结构,但如果它不同,请在第一个管道阶段更改它


也不需要,因为如果该字段不存在,
null
将是默认值。

是否有任何特殊原因使您在Meteor-like
meteorhacks:aggregate
中使用本机mongo驱动程序进行聚合而不是mongo聚合支持?没有,除了我不知道如何使用其他任何东西,我根据SO一起破解了第一个解决方案。我很烂。我想你必须用$addToSet值字段分组、$unwind,然后再用$sum分组。@JanNetherdrake你检查过我的答案了吗?它不起作用吗?有没有什么特别的原因让你使用本机mongo驱动程序进行聚合,而不是Meteor中的mongo聚合支持,比如
meteorhacks:aggregate
?没有,除了我不知道如何使用其他东西之外,我是基于这样的原因一起破解了第一个解决方案。我很烂。我想你必须用$addToSet值字段分组、$unwind,然后再用$sum分组。@JanNetherdrake你检查过我的答案了吗?它不起作用吗?有没有什么特别的原因让你使用本机mongo驱动程序进行聚合,而不是Meteor中的mongo聚合支持,比如
meteorhacks:aggregate
?没有,除了我不知道如何使用其他东西之外,我是基于这样的原因一起破解了第一个解决方案。我很烂。我想你必须用$addToSet值字段分组、$unwind,然后再用$sum分组。@JanNetherdrake你检查过我的答案了吗?它不起作用吗?有没有什么特别的原因让你使用本机mongo驱动程序进行聚合,而不是Meteor中的mongo聚合支持,比如
meteorhacks:aggregate
?没有,除了我不知道如何使用其他东西之外,我黑了第一个解决方案
var sub = this;
    var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;

    var pipeline = [
        { $group: {
            _id: {$ifNull: [ "$data.filename", "NULL" ]},
            count: { $sum: 1 }
        }}
    ];

    db.collection('metadata').aggregate(
        pipeline,

        Meteor.bindEnvironment(
            function(err, result) {
                _.each(result, function(e) {
                  sub.added('installSummary', Random.id(), {
                    filename: e._id,
                    total: e.count
                  });
                });
                sub.ready();
            },
            function(error) {
                Meteor._debug( "Error doing aggregation: " + error);
            }
        )
    );