首页 > 解决方案 > 有条件地排除在 MongoDB 中不起作用的字段

问题描述

我想从数据库中获取一个用户。我的函数接受 a requesterIdwhich 是请求此数据的用户的 ID,a targetIdwhich 是要检索的用户。

如果请求者在目标的friends数组(字符串)中,则该phone字段应包含在投影中。如果不是,则排除。

阅读此处的示例后,我提出了以下查询。但是,phone无论如何,始终返回该字段。我究竟做错了什么?

  getUser: function getUser(requesterId, targetId) {
    return db.collection('users').aggregate([
      {$match: {userId: targetId}},
      {
        $project:
          {
            firstName: 1,
            phone: {
              $cond: {
                if: {friends: requesterId},
                then: "$phone",
                else: "$$REMOVE"
              }
            }
          }
      },
      {$limit: 1}
    ]).toArray();
  }

架构(在 Compass 中创建,因此无需代码):
userId- 字符串
firstName- 字符串
friends- 数组(字符串)
phone- 字符串

指数: 此系列中没有

示例

/* Bob's MongoDB data */ {userId: "BobID", firstName: "Bob", friends: ["AmyID"], phone: "1234567890"}
getUser(requesterId = 'AmyID', targetId = 'BobID');
/* Result */ {firstName: "Bob", phone: "1234567890"}

/* Amy's MongoDB data */ {userId: "AmyID", firstName: "Amy", friends: ["CassieID"], phone: "9876543210"}
getUser(requesterId = 'BobID', targetId = 'AmyID');
/* Result */ {firstName: "Amy", phone: "987654321"}

Bob 对 Amy 用户的请求不应返回她的电话号码,因为他不在她的friends数组中。

标签: mongodbaggregation-frameworkprojection

解决方案


if:值必须是布尔表达式,而不是查询对象。要检查指定值是否在数组中,可以使用$in表达式:

db.collection('users').aggregate([
  {$match: {userId: targetId}},
  {
    $project:
      {
        firstName: 1,
        phone: {
          $cond: {
            if: {$in: [requesterId, '$friends']},
            then: "$phone",
            else: "$$REMOVE"
          }
        }
      }
  },
  {$limit: 1}
])

推荐阅读