【问题标题】:How can I return multiple arrays filtered from one in MongoDb如何返回从 MongoDb 中的一个过滤的多个数组
【发布时间】:2020-03-19 23:30:04
【问题描述】:

我在 MongoDb 数据库中有一些数据,并且正在使用 NodeJS MongoDb Native Driver 访问它。

user: {
    _id: ****Example Id****
    name: 'Foo bar',
    examScores: [
        { subject: 'Geography', score: 80, teacher: 'Mr Foo', date: 'somedate'},
        { subject: 'History', score: 57, teacher: 'Mrs Bar', date: 'somedate'},
        { subject: 'Maths', score: 43, teacher: 'Mrs Fizz', date: 'somedate'},
        { subject: 'Geography', score: 43, teacher: 'Mr Buzz', date: 'somedate'},
        { subject: 'Geography', score: 78, teacher: 'Mr Foo', date: 'somedate'},
        { subject: 'History', score: 41, teacher: 'Mr Buzz', date: 'somedate'}
    ]
}

我想检索每个科目的前十名分数/考试。为简洁起见,我没有在示例中包含超过 10 次考试尝试。

类似:

user: {
    _id: ****Example Id****
    name: 'Foo bar',
    grades: [
        { subject: 'Geography', exams: [ 
            { score: 80, teacher: 'Mr Foo', date: 'somedate' },
            { score: 78, teacher: 'Mr Foo', date: 'somedate' },
            { score: 43, teacher: 'Mr Buzz', date: 'somedate' }
            ]
        },
        { subject: 'History', exams: [
            { score: 57, teacher: 'Mrs Bar', date: 'somedate' },
            { score: 41, teacher: 'Mr Buzz', date: 'somedate'}
            ]
        },
        { subject: 'Maths', exams: [
            { score: 43, teacher: 'Mrs Fizz', date: 'somedate'}
            ]
        }
    ]
}       

【问题讨论】:

    标签: node.js database mongodb aggregation


    【解决方案1】:

    试试这个查询希望它有帮助。我用过$unwind,然后聚合数据。

    db.collection.aggregate([ {$unwind:"$examScores"}, 
    
    {$group:{"_id":"$examScores.subject",name: { $first: "$name" }, exams: { 
    
    $addToSet:{ teacher: '$examScores.teacher' 
    
    ,score:'$examScores.score',date:'$examScores.date' } }}},
    
    {$group:{"_id":null,name: { $first: "$name" }, "grades":{$push: 
    
    {"subject":"$_id", "exams":"$exams"}}}},
    
    {$project:{"_id":0,"grades":1,"name":1}} ])
    

    我得到的预期输出在我的本地机器上

    {
      "name": "Foo bar",
      "grades": [
        {
          "subject": "History",
          "exams": [
            {
              "teacher": "Mr Buzz",
              "score": 41,
              "date": "somedate"
            },
            {
              "teacher": "Mrs Bar",
              "score": 57,
              "date": "somedate"
            }
          ]
        },
        {
          "subject": "Maths",
          "exams": [
            {
              "teacher": "Mrs Fizz",
              "score": 43,
              "date": "somedate"
            }
          ]
        },
        {
          "subject": "Geography",
          "exams": [
            {
              "teacher": "Mr Foo",
              "score": 78,
              "date": "somedate"
            },
            {
              "teacher": "Mr Buzz",
              "score": 43,
              "date": "somedate"
            },
            {
              "teacher": "Mr Foo",
              "score": 80,
              "date": "somedate"
            }
          ]
        }
      ]
    }
    

    【讨论】:

      【解决方案2】:

      请尝试以下查询:

      1. 展开examScores 数组
      2. 根据主题和分数按降序对集合进行排序,因为 您需要按分数降序排列每个科目的结果。
      3. 根据主题分组结果
      4. 因为您只需要列出每个科目的前 10 名最高分 您可以使用$Slice 操作限制前 10 个最高分 每个主题。

        db.collection.aggregate([ 
        
                       { $unwind : "$examScores" },
                       { $sort : 
                               { "examScores.subject" : 1, 
                                 "examScores.score" : -1
                               }
                       }, 
                       { $group : { 
                                  "_id" : "$examScores.subject",
                                  "name" : { $first: "$name" }, 
                                  "examsAll" : { 
                                         $addToSet : { 
                                                teacher: '$examScores.teacher',
                                                score : '$examScores.score',
                                                date : '$examScores.date' 
                                                     } 
                                               }
                                    }
                       },
                       { $project : { 
                                     "_id" : 1, 
                                     "name" : 1, 
                                     "exams" : { $slice: [ "$examsAll", 10 ] } 
                                    }
                       },
                       { $group : { "_id" : null, 
                                    "name" :  { $first: "$name" }, 
                                    "grades" : { $push: 
                                                     { "subject" : "$_id", 
                                                       "exams" : "$exams" 
                                                     }
                                               }
                                   }
                       },
                       { $project : { "_id" : 0,
                                      "grades" : 1,
                                      "name" : 1
                                    }
                       } 
             ]);
        

      【讨论】:

        猜你喜欢
        • 2014-09-11
        • 1970-01-01
        • 1970-01-01
        • 2021-08-12
        • 2015-08-26
        • 2021-11-13
        • 2011-11-06
        • 1970-01-01
        • 2023-02-26
        相关资源
        最近更新 更多