MONGOOSE-仅返回匹配数组过滤器的对象

时间:2020-07-04 20:05:35

标签: node.js mongodb mongoose

我在mongoDB中有一个这样的数据结构

{_id:ObjectId(''),
"awards" : [
               {
                       "award" : "Ballon d'Or",
                       "numberOfTimes" : 6
               },
               {
                       "award" : "Golden Boot",
                       "numberOfTimes" : 6
               },
               {
                       "award" : "FIFA World Player of the Year",
                       "numberOfTimes" : 1
               }
       ],
push:true
}

我目前正在使用这种月光过滤器{'awards.award':"Ballon d'Or"}

我只想在awards数组中返回与Ballon d'Or匹配的对象

所以输出看起来像这样

{_id:ObjectId(''),
"awards" : [
               {
                       "award" : "Ballon d'Or",
                       "numberOfTimes" : 6
               }
       ],
push:true
}

谢谢

3 个答案:

答案 0 :(得分:2)

您可以为此使用projection operator '$'

您可以尝试:

db.collection.find({'awards.award':"Ballon d'Or"}, {'awards.$' : 1})

awards.$:1将仅从awards数组返回匹配的对象。

注意: $(projection)运算符仅返回数组的第一个匹配元素

备用:

如果需要所有匹配的元素,则可以使用聚合管道。 您将需要先展开奖励数组,应用过滤器以仅获得所需结果,然后再次将它们重新组合以获取数组。

对于聚合管道请尝试以下操作:

db.collection.aggregate([
  {
    "$unwind": "$awards"
  },
  {
    $match: {
      "awards.award": "Ballon d'Or"
    }
  },
  {
    $group: {
      _id: "$_id",
      push: {
        $first: "$push"
      },
      awards: {
        $push: "$awards"
      }
    }
  }
])

看看这个MongoDB playground与聚合管道一起玩。

答案 1 :(得分:1)

您可以使用聚合展开管道。

首先,您可以展开数组元素。展开将数组元素分解为文档(或对象)。然后搜索所需的文档。

Model.aggregate([
    $unwind: '$awards',
    $match : {'$award':"Ballon d'Or"}
])

答案 2 :(得分:1)

您只需使用位置运算符$即可实现:

const  = await YourModel.find({'awards.award':"Ballon d'Or"}, "awards.$");

这里的问题是,如果您有许多拥有此勋章的足球运动员。您应该在查询中添加其名称。另外,只会返回与查询匹配的第一个奖项

另一种方法是创建另一个模型并使用受关系数据库启发的外键