【问题标题】:Combine array from embedded document based on condition in MongoDB根据MongoDB中的条件组合来自嵌入式文档的数组
【发布时间】:2015-11-25 14:48:14
【问题描述】:

我收集了如下学生详细信息:

  {
    "Student_id": 1,
    "StudentName": "ABC",
    "TestDetails": [{
            "SubtestName":"Reading", "TestSeq":1, "SubTestDetails":1, 
            "Scores":[{"ScoreType":"YY","ScoreValue":"100"},{"ScoreType":"XX","ScoreValue":"100"},
            {"ScoreType": "ZZ","ScoreValue":"100"}]}]
  ,
    "TestDetails": [{
            "SubtestName":"Writing", "TestSeq":1, "SubTestDetails":2, 
            "Scores":[{"ScoreType":"YY","ScoreValue":"200"},{"ScoreType":"XX","ScoreValue":"200"},
            {"ScoreType": "ZZ","ScoreValue":"200"}]}]
  ,
    "TestDetails": [{
            "SubtestName":"Listning", "TestSeq":2, "SubTestDetails":3, 
            "Scores":[{"ScoreType":"YY","ScoreValue":"300"},{"ScoreType":"XX","ScoreValue":"300"},
            {"ScoreType": "ZZ","ScoreValue":"300"}]}]
  ,
    "TestDetails": [{
            "SubtestName":"Speaking", "TestSeq":2, "SubTestDetails":4, 
            "Scores":[{"ScoreType":"YY","ScoreValue":"400"},{"ScoreType":"XX","ScoreValue":"400"},
            {"ScoreType": "ZZ","ScoreValue":"400"}]}]
  ,
    "TestDetails": [{
            "SubtestName":"Smartness", "TestSeq":3, "SubTestDetails":5, 
            "Scores":[{"ScoreType":"YY","ScoreValue":"500"},{"ScoreType":"XX","ScoreValue":"500"},
            {"ScoreType": "ZZ","ScoreValue":"500"}]}]
  },

  {
    "Student_id": 2,
    "StudentName": "XYZ",
    "TestDetails": [{
            "SubtestName":"Smartness", "TestSeq":1, "SubTestDetails":1, 
            "Scores":[{"ScoreType":"YY","ScoreValue":"100"},{"ScoreType":"XX","ScoreValue":"100"},
            {"ScoreType": "ZZ","ScoreValue":"100"}]}]
  ,
    "TestDetails": [{
            "SubtestName":"Writing", "TestSeq":1, "SubTestDetails":2, 
            "Scores":[{"ScoreType":"YY","ScoreValue":"200"},{"ScoreType":"XX","ScoreValue":"200"},
            {"ScoreType": "ZZ","ScoreValue":"200"}]}]
  ,
    "TestDetails": [{
            "SubtestName":"Listning", "TestSeq":2, "SubTestDetails":3, 
            "Scores":[{"ScoreType":"YY","ScoreValue":"300"},{"ScoreType":"XX","ScoreValue":"300"},
            {"ScoreType": "ZZ","ScoreValue":"300"}]}]
  ,
    "TestDetails": [{
            "SubtestName":"Speaking", "TestSeq":2, "SubTestDetails":4, 
            "Scores":[{"ScoreType":"YY","ScoreValue":"400"},{"ScoreType":"XX","ScoreValue":"400"},
            {"ScoreType": "ZZ","ScoreValue":"400"}]}]
  ,
    "TestDetails": [{
            "SubtestName":"Reading", "TestSeq":3, "SubTestDetails":5, 
            "Scores":[{"ScoreType":"YY","ScoreValue":"100"},{"ScoreType":"XX","ScoreValue":"100"},
            {"ScoreType": "ZZ","ScoreValue":"1000"}]}]
  }, 
  .
  .
  .
)

如何创建聚合查询以生成如下文档:

{Student:1, "TestSeq" : 1, [{Subtest_name: Reading},{Subtest_name: Writing}]},
{Student:1,"TestSeq" :  2, [{Subtest_name: Listning},{Subtest_name: Speaking}]},
{Student:1, "TestSeq" : 3, [{Subtest_name: Smartness}]},
{Student:2, "TestSeq" : 1, [{Subtest_name: Smartness},{Subtest_name: Writing}]},
{Student:2, "TestSeq" : 2, [{Subtest_name: Listning},{Subtest_name: Speaking}]},
{Student:2, "TestSeq" : 3, [{Subtest_name: Reading}]},
{Student:3, "TestSeq" : 1, [{Subtest_name: Subtest1},{Subtest_name: Subtest2}]},
{Student:3, "TestSeq" : 2, [{Subtest_name: Subtest3},{Subtest_name: Subtest4}]},
{Student:3, "TestSeq" : 3, [{Subtest_name: Subtest5}]}

逻辑是根据 TestSeq 值组合/分组子测试名称。例如,子测试名称组合为TestSeq = 1,对于值 2,它位于第 2 行,3 用于每个学生的最后一个子测试名称。

我该如何实现?

我已经尝试如下-

db.students.aggregate([ 
{$unwind: "$SubtestAttribs"},
{ $project: { student_name: 1, student_id : 1,
 print_ready : "$SubtestAttribs.TestSeq",
 Subtest_names :$SubtestAttribs.SubtestName" } } ])

但我无法根据条件形成数组。以上 sn-p 给出了每个测试序列的数据。但是如何根据测试序列合并两个子测试名称呢?

【问题讨论】:

  • 你能告诉我们你尝试了什么吗?我们实际上并没有为您编写代码的习惯。
  • db.students.aggregate([ {$unwind: "$SubtestAttribs"}, { $project: { student_name: 1, student_id : 1, print_ready : "$SubtestAttribs.TestSeq", Subtest_names : " $SubtestAttribs.SubtestName" } } ]) 我无法根据条件形成数组。以上 sn-p 给出了每个测试序列的数据。但是如何根据测试序列组合两个子测试名称?
  • 请编辑您的问题以添加该问题
  • 我还注意到,您的文档在一个文档中多次包含 TestDetails 键。那不是真正合法的 JSON,因为键不是唯一的……您确定那是您的架构真正的样子吗?我认为它应该是单个键 TestDetails,它是您当前拥有的所有 TestDetails 的数组。
  • 另外,您想要的输出也不是合法的 JSON:数组(即[{Subtest_name: Subtest5}])缺少一个键。

标签: mongodb mongodb-query


【解决方案1】:

注意:我做了几个假设,因为您的问题中有一些非法的 JSON。如果我猜错了,请告诉我。另外,我现在不在使用 Mongo 的计算机上,所以我可能有一些语法问题。

db.students.aggregate([
{ $unwind: "$TestDetails" },
{
    $group:{
        _id: { Student: "$Student_id", TestSeq: "$TestDetails.TestSeq},
        Subtest_names: { $addToSet: "$TestDetails.Subtestname" }
    }
},
{
    $project:{
        Student: "$_id.Student",
        TestSeq: "$_id.TestSeq,
        Subtest_names: "$Subtest_names"
    }
}
])

【讨论】:

  • 会把它给你,因为$addToSet 在这里比$push 更合适,所以即使 OP 的 JSON 无效,我也要 +1 :)
  • 感谢您的帮助。我会检查并通知您。
  • 我低于 o/p - { "_id" : { "Student" : 2, "TestSeq" : 3 }, "Subtest_names" : [ "Reading" ], "Student" : 2 , "TestSeq" : 3 } { "_id" : { "Student" : 1, "TestSeq" : 3 }, "Subtest_names" : [ "Smartness" ], "Student" : 1, "TestSeq" : 3 } .. ...在这里,我为每个学生获取一个数据,而我需要根据每个测试序列查找子测试名称列表。
  • 将行 Subtest_names: { $addToSet: "$TestDetails.Subtestname" } 更改为 "details": { "$addToSet": { "Subtest_name": "$TestDetails.SubtestName" } } 以使其工作。
  • 谢谢。它格式化了o/p。但是如何根据 TestSeq 为同一个学生获取多行?例如: {Student:1, "TestSeq" : 1, [{Subtest_name: Reading},{Subtest_name: Writing}]}, {Student:1,"TestSeq" : 2, [{Subtest_name: Listning},{Subtest_name:口语}]}, {Student:1, "TestSeq" : 3, [{Subtest_name: Smartness}]}, {Student:2, "TestSeq" : 1, [{Subtest_name: Smartness},{Subtest_name: Writing}]} ,{学生:2,“TestSeq”:2,[{Subtest_name:Listning},{Subtest_name:Speaking}]},{Student:2,“TestSeq”:3,[{Subtest_name:Reading}]},
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-07
  • 1970-01-01
  • 2021-10-24
  • 2018-05-09
相关资源
最近更新 更多