按ID对聚合匹配组进行排序

时间:2016-11-25 10:37:30

标签: 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,
        "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)。有什么想法吗?

感谢阅读。

3 个答案:

答案 0 :(得分:1)

以下是您的查询的解决方案。

    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"}
        }
    }
])

或者您可以使用 $ filter 选项 $ project

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"
            }
        ]
    }
}

答案 1 :(得分:0)

得到了我的答案:

How to retrieve all matching elements present inside array in Mongo DB?

使用$ group one中的$ addToSet属性。

答案 2 :(得分:0)

这是查询,它是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"
            }
        }
    }
}