聚合到输出嵌套列表

时间:2017-06-09 08:20:01

标签: mongodb mongodb-query aggregation-framework

我一直面临着获得我想要的输出的一些问题。下面是我的名为" testdata_4":

的集合中的示例数据结构
[
    {
        "_id": 1,
        "Record": 1,
        "Link": "www.google.com",
        "Link_Title": "Google",
        "Location": ["loc1", "loc2", "loc3", "loc4"],
        "Date": 2017,
        "People": ["ppl1", "ppl2", "ppl3", "ppl4"]
    },
    {
        "_id": 2,
        "Record": 2,
        "Link": "www.facebook.com",
        "Link_Title": "Facebook",
        "Location": ["loc1", "loc2", "loc3", "loc4"],
        "Date": 2016,
        "People": ["ppl1", "ppl2", "ppl3", "ppl4"]
    }
]

我尝试使用的查询是:

db.testdata_4.aggregate([{
    "$unwind": "$Location"
},{
    "$group": {
        "_id": {
            "Locations": "$Location",
            "Year": "$Date"
        },
        Links: {
            $addToSet: "$Link"
        },
        Titles: {
            $addToSet: "$Title"
        }
    }
}, {
    "$sort": { "_id.Year": 1 }
},{
    "$group": {
        "_id": "$_id.Locations",
        Records: {
            $push: {
                "Year": "$_id.Year",
                "Links": { $setUnion: ["$Links", "$Titles"]}
            }
        }
    }
},{
    "$sort": { "_id": 1 }
}]).toArray()

我从上面的查询得到的输出是:

[
    {
        "_id" : "loc2",
        "Records" : [
            {
                "Year" : 2016,
                "Links" : [
                    "CooCoo",
                    "Facebook",
                    "Google",
                    "www.coocoo.com",
                    "www.facebook.com",
                    "www.google.com"
                ]
            }
        ]
    },
    {
        "_id" : "loc3",
        "Records" : [
            {
                "Year" : 2017,
                "Links" : [
                    "CooCoo",
                    "Facebook",
                    "www.coocoo.com",
                    "www.facebook.com"
                ]
            }
        ]
    }
]

然而,我上面得到的输出是我希望获得的输出稍微偏离,这应该看起来像下面的示例输出(重新使用上面的输出):

[
    {
        "_id" : "loc2",
        "Records" : [
            {
                "Year" : 2016,
                "Links" : [
                    {"Title":"CooCoo", "Link":"www.coocoo.com"},
                    {"Title":"Facebook", "Link":"www.facebook.com"},
                    {"Title":"Google", "Link":"www.google.com"}
                ]
            }
        ]
    },
    {
        "_id" : "loc3",
        "Records" : [
            {
                "Year" : 2017,
                "Links" : [
                    {"Title": "CooCoo", "Link":"www.coocoo.com"},
                    {"Title": "Facebook", "Link":"www.facebook.com"}                    
                ]
            }
        ]
    }
]

所以我的问题是,我是否有可能聚合并获得我想要的输出,或者根本不可能?如果可能的话,只要它能帮助我进步一点,任何提供的解决方案都会受到欢迎!提前谢谢!

2 个答案:

答案 0 :(得分:2)

如果我正确地阅读了您的意图,那么您将所有内容分组为不同的值,而不是$addToSet

db.testdata_4.aggregate([
  { "$unwind": "$Location" },
  { "$group": {
    "_id": {
      "Location": "$Location",
      "Year": "$Date",
      "Title": "$Link_Title",
      "Link": "$Link"
    }
  }},
  { "$group": {
    "_id": {
      "Location": "$_id.Location",
      "Year": "$_id.Year",
    },
    "Links": { "$push": {
      "Title": "$_id.Title",
      "Link": "$_id.Link"
    }}
  }},
  { "$sort": { "_id.Year": 1 } },
  { "$group": {
    "_id": "$_id.Location",
    "Records": {
      "$push": {
        "Year": "$_id.Year",
        "Links": "$Links"
      }
    }
  }}
])

因此,在您$unwind数组之后,您将所有内容放入_id的{​​{1}}键中以获取不同的值。

然后,只需先按位置和年份进行分组,然后创建"链接"数组,然后再次分组创建"记录"阵列。

答案 1 :(得分:1)

此查询也可能会为您提供预期的输出

db.testdata_4.aggregate([
  {"$unwind": "$Location"},
  {"$group": {
    _id: {"Locations": "$Location","Year": "$Date"},
    Links: { $addToSet: {Link: "$Link", Title: "$Link_Title"}}
  }},
  {"$sort": {"_id.Year": 1}},
  {"$group": {
    "_id": "$_id.Locations",
    Records: {$push: {"Year": "$_id.Year", "Links": "$Links"}}
  }},
  {"$sort": {"_id": 1}}
]).toArray()