【问题标题】:How to find a subdocument by id in mongoose and exclude some fields如何在猫鼬中按id查找子文档并排除某些字段
【发布时间】:2015-08-10 14:35:22
【问题描述】:

我有一个存储在 mongodb 中的文档:

shop: {
  _id: '...'
  title: 'my shop'
  users: [
    {
      _id: '...',
      name: 'user1',
      username: '...'
    },
    {
      _id: '...',
      name: 'user2',
      username: '...'
    }
  ]
}

我使用此查询通过他的 id 获取子文档用户:

Shop.findOne({'users._id': userId}, {'users.$': 1}, function (err, user) {
  console.log(user);
});

输出:

{ _id: ...,
  users: 
   [{
     name: 'user1',
     username: '...',
     _id: ...
    }]
}

如何过滤结果以仅返回用户名。 我现在的做法:

Shop.findOne({'users._id': userId}, {'users.$': 1}, function (err, shop) {
  shop = shop.toObject()
  user = shop.users[0]
  filtered = {
    name: user.name
  }
  callback(filtered);
});

但是有没有更好的方法在查询中完成这一切?

【问题讨论】:

    标签: mongodb mongoose


    【解决方案1】:

    这个问题已经快两年了,但我注意到人们仍在寻找解决这个问题的方法。 fernandopasik 的回答对我帮助很大,但缺少有关如何使用建议的聚合操作的代码示例。这就是为什么我发布更详细的答案。 我使用的文档是:

    {
      _id: '...'
      title: 'my shop'
      users: [
        {
          _id: 'user1Id',
          name: 'user1',
          username: '...'
        },
        {
          _id: 'user2Id',
          name: 'user2',
          username: '...'
        }
      ]
    }
    

    我想出的解决方案(在阅读了关于聚合的 mongodb 文档之后)是:

    Shop.aggregate([
      {$unwind: '$users'},
      {$match: {'users._id': 2}},
      {$project: {_id: 0, 'name': '$users.name'}}
    ]);
    

    要了解聚合是如何工作的,最好一次尝试一个操作并阅读该操作的 mongodb 文档。

    1. Shop.aggregate([{$unwind: '$users'}])

    $unwind 解构 users 数组(不要忘记在数组名称中包含 $),所以你最终得到:

    {
      _id: '...',
      title: 'my shop',
      users: {
        _id: 'user1Id',
        name: 'user1',
        username: '...'
      }
    }
    {
      _id: '...',
      title: 'my shop',
      users: {
        _id: 'user2Id',
        name: 'user2',
        username: '...'
      }
    }
    

    2。在聚合管道(本例中的两个文档)上使用 {$match: {'users._id': 'user2Id'}} 将返回 users._id 为 'user2Id' 的整个文档:

    {
      _id: '...',
      title: 'my shop',
      users: {
        _id: 'user2Id',
        name: 'user2',
        username: '...'
      }
    }
    

    3。只返回名称:'user2' 你可以使用{$project: {_id: 0, 'name': '$users.name'}}:

    {name: 'user2'}
    

    聚合管道一开始并不容易掌握。我建议通读 mongodb 聚合文档并一次尝试一个聚合操作。有时很难在整个聚合管道中发现错误。大多数情况下,当管道中某处出现错误时,您根本无法从管道中获得任何结果文档。

    【讨论】:

      【解决方案2】:

      您应该尝试使用 mongoose 的 mongodb 聚合框架:

      http://mongoosejs.com/docs/api.html#aggregate-js

      我建议你先应用 unwind 用户,然后 ma​​tch 用户 id,然后 project 用户名。

      【讨论】:

      • 我不明白如何使用这种方法,也许是小例子,使用它会很感激
      猜你喜欢
      • 2020-07-25
      • 2016-06-17
      • 2016-10-13
      • 1970-01-01
      • 2020-12-02
      • 2019-07-17
      • 1970-01-01
      • 1970-01-01
      • 2022-12-10
      相关资源
      最近更新 更多