Mongodb 按聚合中的id对匹配组进行排序

Mongodb 按聚合中的id对匹配组进行排序,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,(这里是Mongo新手,对不起)我有一个mongodb集合,它是具有此模式的mapreduce的结果: { "_id" : "John Snow", "value" : { "countTot" : 500, "countCall" : 30, "comment" : [ { "text" : "this is a text", "date" : 2016-11-17 00:00:00.000Z, "ty

(这里是Mongo新手,对不起)我有一个mongodb集合,它是具有此模式的mapreduce的结果:

{
  "_id" : "John Snow",
  "value" : {
    "countTot" : 500,
    "countCall" : 30,
    "comment" : [
      {
        "text" : "this is a text",
        "date" : 2016-11-17 00:00:00.000Z,
        "type" : "call"
      },
      {
        "text" : "this is a text",
        "date" : 2016-11-12 00:00:00.000Z,
        "type" : "visit"
      },
      ...
    ]
  }
}
我的目标是创建一个包含特定类型的所有注释的文档。例如,包含所有调用的文档John snow

我使用以下方法获得了特定类型的所有注释:

db.general_stats.aggregate(

    { $unwind: '$value.comment' },

    { $match: {
        'value.comment.type': 'call'
    }}
)
但是,即使使用$group属性,我也找不到对ID(例如john snow)接收的数据进行分组的方法。有什么想法吗


谢谢你的阅读

我的答案是:


使用$group one中的$addToSet属性

我的答案是:


使用$group one中的$addToSet属性

这里是查询,它是OP中存在的查询的扩展

db.general_stats.aggregate(
    { $unwind: '$value.comment' },
    { $match: {
        'value.comment.type': 'call'
    }},
    {$group : {_id : "$_id", allValues : {"$push" : "$$ROOT"}}},
    {$project : {"allValues" : 1, _id : 0} },
    {$unwind : "$allValues" }
);
输出:-

{
    "allValues" : {
        "_id" : "John Snow",
        "value" : {
            "countTot" : 500,
            "countCall" : 30,
            "comment" : {
                "text" : "this is a text",
                "date" : ISODate("2016-11-25T10:46:49.258Z"),
                "type" : "call"
            }
        }
    }
}

下面是一个查询,它是OP中存在的查询的扩展

db.general_stats.aggregate(
    { $unwind: '$value.comment' },
    { $match: {
        'value.comment.type': 'call'
    }},
    {$group : {_id : "$_id", allValues : {"$push" : "$$ROOT"}}},
    {$project : {"allValues" : 1, _id : 0} },
    {$unwind : "$allValues" }
);
输出:-

{
    "allValues" : {
        "_id" : "John Snow",
        "value" : {
            "countTot" : 500,
            "countCall" : 30,
            "comment" : {
                "text" : "this is a text",
                "date" : ISODate("2016-11-25T10:46:49.258Z"),
                "type" : "call"
            }
        }
    }
}

这是您的查询的解决方案

    db.getCollection('calls').aggregate([
    { $unwind: '$value.comment' },
    { $match: {
        'value.comment.type': 'call'
    }},
    { 
        $group : {
            _id : "$_id",
            comment : { $push : "$value.comment"},
            countTot : {$first : "$value.countTot"},
            countCall : {$first : "$value.countCall"},
        }
    },
    {
        $project : {
            _id : 1,
            value : {"countTot":"$countTot","countCall":"$countCall","comment":"$comment"}
        }
    }
])
或者您可以使用$project$filter选项

db.getCollection('calls').aggregate([
    {
      $project: {
         "value.comment": {
            $filter: {
               input: "$value.comment",
               as: "comment",
               cond: { $eq: [ "$$comment.type", 'call' ] }
            }
         },
         "value.countTot":"$value.countTot",
         "value.countCall":"$value.countCall",
      }
   }
])
在这两种情况下,下面都是我的输出

{
    "_id" : "John Snow",
    "value" : {
        "countTot" : 500,
        "countCall" : 30,
        "comment" : [ 
            {
                "text" : "this is a text",
                "date" : "2016-11-17 00:00:00.000Z",
                "type" : "call"
            }, 
            {
                "text" : "this is a text 2",
                "date" : "2016-11-17 00:00:00.000Z",
                "type" : "call"
            }
        ]
    }
}

这是您的查询的解决方案

    db.getCollection('calls').aggregate([
    { $unwind: '$value.comment' },
    { $match: {
        'value.comment.type': 'call'
    }},
    { 
        $group : {
            _id : "$_id",
            comment : { $push : "$value.comment"},
            countTot : {$first : "$value.countTot"},
            countCall : {$first : "$value.countCall"},
        }
    },
    {
        $project : {
            _id : 1,
            value : {"countTot":"$countTot","countCall":"$countCall","comment":"$comment"}
        }
    }
])
或者您可以使用$project$filter选项

db.getCollection('calls').aggregate([
    {
      $project: {
         "value.comment": {
            $filter: {
               input: "$value.comment",
               as: "comment",
               cond: { $eq: [ "$$comment.type", 'call' ] }
            }
         },
         "value.countTot":"$value.countTot",
         "value.countCall":"$value.countCall",
      }
   }
])
在这两种情况下,下面都是我的输出

{
    "_id" : "John Snow",
    "value" : {
        "countTot" : 500,
        "countCall" : 30,
        "comment" : [ 
            {
                "text" : "this is a text",
                "date" : "2016-11-17 00:00:00.000Z",
                "type" : "call"
            }, 
            {
                "text" : "this is a text 2",
                "date" : "2016-11-17 00:00:00.000Z",
                "type" : "call"
            }
        ]
    }
}