如何在findOne中的猫鼬中过滤嵌套数组而无需嵌套对象

时间:2020-09-07 23:05:55

标签: node.js mongodb mongoose

我有一个称为选举的集合,在选举模式中有一个称为投票的嵌套数组。我正在尝试通过ID查询选举,并通过userId属性过滤嵌套的投票对象。我希望始终返回父选举对象,如果当前用户尚未在选举中投票,则votes属性应该为空数组。

这是我的查询:

Election.findOne({
    _id: electionId,
    'votes.userId': userId
})
.exec()

问题在于,如果userId没有任何投票,那么父选举对象也不会返回。有什么方法可以过滤votes属性,但也可以使其与父选举对象匹配时不需要。

我来自sql的背景,在Sequelize中,这是我想做的事情:

models.Election.findOne({
    where: {
        id: electionId
    }
    include: {
        model: models.Vote,
        where: {
            userId
        },
        required: false
    }
})

1 个答案:

答案 0 :(得分:1)

MongoDB有一个$filter aggregation

const res = await Election.aggregate([
  { $match: { _id: mongoose.Types.ObjectId(electionId) } },
  { $project: {
      _id: 1,
      votes: { $filter: {
        input: '$votes',
        as: 'userVote',
        cond: { $eq: [ '$$userVote', userId ] },
      }}
  }}
])

相当于普通的js过滤器

votes.filter(userVote => userVote.userId === userId)

question on filtering arrays in mongodb的其他答案也很相关,但那里的查询要求与您的问题稍有不同,更像是您的初次尝试。