【问题标题】:Conditional field selection with Mongoose使用 Mongoose 进行条件字段选择
【发布时间】:2018-01-10 07:55:12
【问题描述】:

假设我有一组具有用户名和电子邮件地址的用户。

{ name: 'John Doe', email: 'john@doe.com', level: 5 }
{ name: 'Fred Foo', email: 'fred@foo.com', level: 2 }
{ name: 'Jo Green', email: 'jo@green.com', level: 5 }
{ name: 'Paul Bar', email: 'paul@bar.com', level: 3 }

我想查询这个集合,选择所有用户的名字和级别。在 Mongoose 中,我可以这样做:

User
  .find()
  .select('name level')
  .exec(callback)

这会给我以下信息:

{ name: 'John Doe', level: 5 }
{ name: 'Fred Foo', level: 2 }
{ name: 'Jo Green', level: 5 }
{ name: 'Paul Bar', level: 3 }

但如果用户的级别高于 4,我还想获取他们的电子邮件地址。这会给我以下信息:

{ name: 'John Doe', email: 'john@doe.com', level: 5 }
{ name: 'Fred Foo', level: 2 }
{ name: 'Jo Green', email: 'paul@bar.com', level: 5 }
{ name: 'Paul Bar', level: 3 }

Mongo[ose] 最好的是什么?

【问题讨论】:

  • 要么做 2 个查询(一个 > 4,另一个
  • 这是我实际尝试做的(非常)简化的版本。在查询之后编写代码来处理它将是一项艰巨的任务。我希望有一种方法可以使用 mapReduce 或聚合管道或类似的东西。
  • 那么你到底想做什么?知道这一点会有所帮助。

标签: mongodb mongoose


【解决方案1】:

不,目前在 MongoDb 中无论如何都没有在一个查询中根据条件选择性地返回不同的字段集。 MongoDb 中的查询和关联的投影适用于所有文档。

map reduce 无法做到这一点(因为 map reduce 需要为每个文档返回相同的值)并且不适合。聚合不是许多查询的通用替代方案,并且有条件地返回字段会很复杂。

你有几个选择:

  1. 执行多个查询并合并结果。这将非常简单,因为每个结果都是一个数组,因此您可以合并数组。
  2. 返回所有字段的超集并在您的应用代码中过滤。

我会测试选项的性能。两者都不复杂。

【讨论】:

    【解决方案2】:

    正如 WiredPrairie 所说,这在一个查询中是不可能的。它可以使用聚合和一些应用程序代码轻松完成。要仅返回级别高于 4 的电子邮件,可以使用以下聚合:

    User.aggregate().match({})
      .project({
        'name': 1,
        'email': {
          $cond: {
            if: {
              '$gt': ['$level', 4]
            },
            then: '$email',
            else: null
          }
        },
        'level': 1
      })
      .exec(callback);

    使用 lodash 或 underscore 之类的实用程序库可以直接删除结果集中的任何空电子邮件。在回调函数中,以下 lodash 函数将删除所有空电子邮件:

    var callback = function(err, users) {
      return _.map(users, function(user) {
        return _.omitBy(user, _.isNull);
      });
    };

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-12
      • 2012-10-16
      • 2016-12-21
      • 1970-01-01
      • 2014-11-15
      • 2020-12-22
      • 2018-12-04
      • 1970-01-01
      相关资源
      最近更新 更多