从Mongodb中的每条记录的数组中获取唯一值

时间:2016-02-29 18:38:26

标签: mongodb database nosql

我在MongoDB中有一个如下所示的集合:

{
    "_id" : ObjectId("56d3e53b965b57e4d1eb3e71"),
    "name" : "John",
    "posts" : [
                 {
                    "topic" : "Harry Potter",
                    "obj_ids" : [
                            "1234"
                    ],
                    "dates_posted" : [
                            "2014-12-24"
                    ]
                 },
                 {
                    "topic" : "Daniel Radcliffe",
                    "obj_ids" : [
                            "1235",
                            "1236",
                            "1237"
                    ],
                    "dates_posted" : [
                            "2014-12-22",
                            "2015-01-13",
                            "2014-12-24"
                    ]
                 }
              ],
},
{
    "_id" : ObjectId("56d3e53b965b57e4d1eb3e72"),
    "name" : "Jane",
    "posts" : [
                 {
                    "topic" : "Eragon",
                    "tweet_ids" : [
                            "1672",
                            "1673",
                            "1674"
                    ],
                    "dates_posted" : [
                            "2014-12-27",
                            "2014-11-16"
                    ]
                }
            ],
}

我如何查询以获得如下结果:

{
       "name": "John",
       "dates": ["2014-12-24", "2014-12-22", "2015-01-13"]
},
{
       "name": "Jane",
       "dates" : ["2014-12-27", "2014-11-16"]
}

我需要日期是独特的,因为" 2014-12-24"出现在"posts"的两个元素中,但我只需要一个。

我尝试了db.collection.aggregate([{$unwind: "$posts"}, {$group:{_id:"$posts.dates_posted"}}]),这给了我这样的结果:

{ "_id" : [ "2014-12-24", "2014-12-22", "2015-01-13", "2014-12-24" ] }
{ "_id" : [ "2014-12-27", "2014-11-16" ] }

如何删除重复项并获取与日期对应的名称?

1 个答案:

答案 0 :(得分:1)

您需要使用$addToSet运算符来维护唯一值。一种方法是:

  • unwind帖子。
  • unwind" posts.date_posted",以便数组变平,价值可以在小组阶段汇总。
  • 然后group _id,并累计日期字段的唯一值以及name

代码:

db.collection.aggregate([
{
  $unwind:"$posts"
},
{
  $unwind:"$posts.dates_posted"
},
{
  $group:
         {
           "_id":"$_id",
           "dates":{$addToSet:"$posts.dates_posted"},
           "name":{$first:"$name"}
         }
},
{
  $project:
            {
              "name":1,
              "dates":1,
              "_id":0
            }
}
])

这种方法的缺点是,它使用两个unwind阶段,这是昂贵的,因为它会增加文件的数量,输入到后续阶段,乘以{{1}其中n是数组中被展平的值的数量。