如何在mongoDB中过滤子文档?

时间:2016-05-06 09:43:53

标签: javascript node.js mongodb mongoose

我有这个mlab文档:

{
"_id": {
    "$oid": "572b2cdfc80eb653c302f5e9"
},
"year": 2014,
"students": [
    {
        "id": 5,
        "firstName": "Joe",
        "lastName": "know",
        "GPA": 67
    },
    {
        "id": 3,
        "firstName": "Peter",
        "lastName": "Jones",
        "GPA": 77
    },
    {
        "id": 6,
        "firstName": "Yossi",
        "lastName": "Haim",
        "GPA": 68
    },
    {
        "id": 13,
        "firstName": "Chen",
        "lastName": "Si",
        "GPA": 92
    }
]
}

我得到的:(年份也是一个参数)

gradeM= mongoose.model('Grade',grade);
      gradeM.find({'year':year},'-_id').exec(function (err, data) {
          if (err) console.log("err: " + err);
      console.log(JSON.stringify(data)); 
  });

尽管从集合中获取数据我做得很好,但我希望从返回的文档中排除GPA <90的所有学生阵列记录。 尝试了一些不同的聚合和匹配函数,但我似乎无法使语法正确。

最终结果应如下所示:

 {
   "year": 2014,
   "students": [
    {
        "id": 13,
        "firstName": "Chen",
        "lastName": "Si",
        "GPA": 92
    }
]
}

我总是可以使用JS循环文档,但我正在寻找一种方法来立即获得准备结果。
感谢

3 个答案:

答案 0 :(得分:2)

您可以尝试使用聚合

gradeM.aggregate( {$match: {year: 2014}},{ $unwind: '$students'},
                   { $match: {'students.GPA': {$lt: 90}}},
                   { $group: {_id: '$_id',
                              year : '$year',
                              students: {$push: {id:'$students.id',
                                                 firstName:'$students.firstName'}}}})

输出:

{ "_id" : ObjectId("572b2cdfc80eb653c302f5e9"), 
  "year":2014,
   "students" : [ { "id" : 5, "firstName" : "Joe" },
                  { "id" : 3, "firstName" : "Peter" },
                  { "id" : 6, "firstName" : "Yossi" } ] }

另外,你可以试试

gradeM.aggregate([
    { $match: {year: year}},
    { $project: {
        students: {$filter: {
            input: '$students',
            as: 'students',
            cond: {$lt: ['$$students.GPA', 90]}
        }}
        }}
    ])

答案 1 :(得分:2)

您可以使用$elemMatch

尝试以下

gradeM= mongoose.model('Grade',grade);
  gradeM.find({'year':year, students: { $elemMatch: GPA: { $lt: 90 } }},'-_id').exec(function (err, data) {
      if (err) console.log("err: " + err);
  console.log(JSON.stringify(data)); 
  });

答案 2 :(得分:1)

你可以放松学生,过滤它们,然后添加到组 - 请参阅下面的示例:

db.yush.aggregate([
{$match:{"year":2014}},
{
            $unwind : "$students"
        }, {
            $match : {
                "students.GPA" : {
                    $lt : 90
                }                
            }
        }, {
            $group : {
                _id : "$year"
                ,
                students : {
                    $push : "$students"
                }
            }
        }
    ])

最后使用$ project将_id更改为年份

玩得开心 - 欢迎任何评论!