MongoDB 在数组中创建数组

MongoDB create an array within an array

我正在努力了解 MongoDB 以及聚合和组。到目前为止,我已经度过了大约 3 天。

我的源数据看起来像...

{
   "formName" : "my form",
   "updatedAt" : "2021-11-02T13:29:00.123Z",
},
{
   "formName" : "another form",
   "lastUpdated" : "2021-10-01T13:29:00.123123",
},

请注意,可能有不同的日期名称,尽管这些是唯一的区别。

我正在尝试实现...

{
    "_id": null,
    "text": "my form",  (NOTE: This is the formName)
    "children": [{
       "text" : 2021, (This is the year part of the updated)
       "children" : [
          {"text" : 1}, (These are the month part of the updated)
          {"text" : 2},
          {"text" : 3},
          {"text" : 4}
       ]
    },
    ]
}

所以,基本上是一棵树,它有 formName,有年的子分支,有月的子分支。

我尝试了各种方法,很多都不行,比如在 $groups 中嵌套 $addToSet。

我已经接近了,但是我无法解决

这是最接近的,但这行不通。

db.FormsStore.aggregate( [
  
  {$match:{myKey:"a guid to group my forms together"}},
  {$project: {formName:1, lastUpdated:1, updatedAt:1}},
  { 
    $group: { 
      _id:   { formName: "$formName" }, 
      Year: {$addToSet: {$year: {$dateFromString: { dateString: "$lastUpdated" }}}},
      Month: {$addToSet: {$month: {$dateFromString: { dateString: "$lastUpdated" }}}},
    } 
  }, 
  { 
    $group: {
      _id: { formName: "$_id.formName" }, 
     Time: {$addToSet: {year: "$Year", month: "$Month"}}
    } 
  } 
]
)

输出显示...

{ 
    _id: { formName: 'One of my forms' },
    Time: [
      {
        year: [ 2021 ],
        month: [ 10, 11 ] 
      }
    ]
 }

这将全部用于C#

非常感谢您的帮助。

查询

  • 添加一个新字段“日期”,日期格式为日期
  • 首先将更具体的 (formname+year) 分组以将月份放入数组中
  • 分组然后将不太具体的 (formname) 放在数组中
aggregate(
[{"$set": 
    {"date": 
      {"$cond": 
        ["$updatedAt", {"$dateFromString": {"dateString": "$updatedAt"}},
          {"$dateFromString": {"dateString": "$lastUpdated"}}]},
      "updatedAt": "$$REMOVE",
      "lastUpdated": "$$REMOVE"}},
  {"$group": 
    {"_id": {"text": "$formName", "year": {"$year": "$date"}},
      "children": {"$push": {"text": {"$month": "$date"}}}}},
  {"$group": 
    {"_id": "$_id.text",
      "children": 
      {"$push": {"text": "$_id.year", "children": "$children"}}}},
  {"$set": {"text": "$_id", "_id": "$$REMOVE"}}])

编辑

波纹管也按 year/month 排序,并且每个 formName 只保留唯一的 year/months。

  • 区别在于按 formName,year,month 分组取唯一(第一个 aacumulator 将只取所有 3 个相同的那些中的一个)
  • replace-root(使第一个文件成为ROOT文件)
  • 然后按这 3 个字段排序(年份降序,月份升序)
  • 按 2 个字段排序
  • 最后一组

PlayMongo
*mongoplaygroung 丢失了字段的顺序,运行 它在你的驱动程序上也可以确定

aggregate(
[{"$set": 
    {"date": 
      {"$cond": 
        ["$updatedAt", {"$dateFromString": {"dateString": "$updatedAt"}},
          {"$dateFromString": {"dateString": "$lastUpdated"}}]},
      "updatedAt": "$$REMOVE",
      "lastUpdated": "$$REMOVE"}},
  {"$set": {"year": {"$year": "$date"}, "month": {"$month": "$date"}}},
  {"$group": 
    {"_id": {"formName": "$formName", "year": "$year", "month": "$month"},
      "doc": {"$first": "$$ROOT"}}},
  {"$replaceRoot": {"newRoot": "$doc"}},
  {"$sort": {"formName": 1, "year": -1, "month": 1}},
  {"$group": 
    {"_id": {"text": "$formName", "year": "$year"},
      "children": {"$push": {"text": "$month"}}}},
  {"$sort": {"_id.text": 1, "_id.year": -1}},
  {"$group": 
    {"_id": "$_id.text",
      "children": 
      {"$push": {"text": "$_id.year", "children": "$children"}}}},
  {"$set": {"text": "$_id", "_id": "$$REMOVE"}}])

有数据

[
  {
    "formName": "my form",
    "updatedAt": "2021-11-02T23:30:15.123Z"
  },
  {
    "formName": "my form",
    "updatedAt": "2021-10-02T23:30:15.123Z"
  },
  {
    "formName": "my form",
    "updatedAt": "2020-06-02T23:30:15.123Z"
  },
  {
    "formName": "my form",
    "updatedAt": "2020-07-02T23:30:15.123Z"
  },
  {
    "formName": "another form",
    "updatedAt": "2021-10-01T23:30:15.123Z"
  },
  {
    "formName": "another form",
    "updatedAt": "2021-10-01T23:30:15.123Z"
  },
  {
    "formName": "another form",
    "updatedAt": "2021-09-01T23:30:15.123Z"
  },
  {
    "formName": "another form",
    "updatedAt": "2021-08-01T23:30:15.123Z"
  },
  {
    "formName": "another form",
    "updatedAt": "2020-10-01T23:30:15.123Z"
  }
]

我得到了结果

[{
  "children": [
    {
      "text": 2021,
      "children": [
        {
          "text": 10
        },
        {
          "text": 11
        }
      ]
    },
    {
      "text": 2020,
      "children": [
        {
          "text": 6
        },
        {
          "text": 7
        }
      ]
    }
  ],
  "text": "my form"
},
{
  "children": [
    {
      "text": 2021,
      "children": [
        {
          "text": 8
        },
        {
          "text": 9
        },
        {
          "text": 10
        }
      ]
    },
    {
      "text": 2020,
      "children": [
        {
          "text": 10
        }
      ]
    }
  ],
  "text": "another form"
}]

我继续努力,虽然这也不是很正确(但),但这是我想出的。

db.FormsStore.aggregate([
  
  {$project: {formName:1, lastUpdated:1, updatedAt:1}},
  { 
    $group: { 
      _id: {formName: "$formName", Year: {$year: {$dateFromString: { dateString: "$updatedAt" }}}, Month: {$month: {$dateFromString: { dateString: "$updatedAt" }}}},
    } 
  },
  {
    $group: {
        _id: {formName: "$_id.formName", Year: "$_id.Year"}, 
        Months: {$addToSet: {Text: "$_id.Month"}}
    }
  },
  {
    $group: {
        _id:  "$_id.formName", Children: {$addToSet: {Text: "$_id.Year", Children: "$Months"}}, 
        
    }
  }
])

在第一组中获取我的所有数据,然后在第二组中创建一个包含月份的集合,然后在第三组中创建一个包含年份的集合并将月份添加到每年。