如何在MongoDB$投影中使用$arrayElemAt并从该元素中删除字段?

如何在MongoDB$投影中使用$arrayElemAt并从该元素中删除字段?,mongodb,mongoose,Mongodb,Mongoose,我有“工作”和“用户”集合。每个用户都可以为给定的“jobCategoryId”创建一个作业,然后该作业保存在“jobs”集合中,并包含其创建者的“userId”和“jobCategoryId” 我正在尝试合并这两个集合,因此当我获取作业时,我将在所有用户数据中使用“user”字段,而不是该作业的“userId”字段。我现在就是这样做的: Job.aggregate([{ $match: { jobCategoryId: mongoose.Types.ObjectId(jobCate

我有“工作”和“用户”集合。每个用户都可以为给定的“jobCategoryId”创建一个作业,然后该作业保存在“jobs”集合中,并包含其创建者的“userId”和“jobCategoryId”

我正在尝试合并这两个集合,因此当我获取作业时,我将在所有用户数据中使用“user”字段,而不是该作业的“userId”字段。我现在就是这样做的:

Job.aggregate([{
  $match: {
    jobCategoryId: mongoose.Types.ObjectId(jobCategoryId)
  }
}, {
  $lookup: {
    from: 'users',
    localField: 'userId',
    foreignField: '_id',
    as: 'user'
  }
}, {
  $project: {
    _id: 1,
    description: 1,
    title: 1,
    user: { $arrayElemAt: ['$user', 0] }
  }
}, {
  $project: {
    _id: 1,
    title: 1,
    description: 1,
    'user.name': '$user.name'
  }
}])
这将返回以下结果:

[{
  _id: 'some id',
  title: 'title',
  description: 'description',
  user: {
    name: 'Mike'
  }
}]
结果是正确的,但我真的很感兴趣,如果有任何其他方法,以保持只有一些字段从用户对象直接使用$arrayElemAt,还是我注定要使用管道中的2个投影?
有人能帮我解决这个小问题吗?非常感谢。

这是从

表达式可以是任何有效的表达式,只要 解析为数组

这意味着您可以根据需要构造数组元素。在您的情况下,您只需要名称。因此,这应该是可行的:

[{
  $match: {
    jobCategoryId: mongoose.Types.ObjectId(jobCategoryId)
  }
}, {  
  $lookup: {  
    from: 'users',
    localField: 'userId',
    foreignField: '_id',
    as: 'user'
  }
}, {  
  $project: {  
    _id: 1,
    description: 1,
    title: 1,
    user: {  
      name: {
        $arrayElemAt: ["$user.name", 0]
      }
    }
  }
}]
后续更新: 有人问它如何在
名称
上添加其他属性。以下是项目:

{  
  $project: {  
    _id: 1,
    description: 1,
    title: 1,
    user: {  
      name: {  
        $arrayElemAt: ["$user.name", 0]
      },
      email: {  
        $arrayElemAt: ["$user.email", 0]
      }
    }
  }
}
第二次跟进如Drag0在评论中所问:如果由于结果生成大小为1的用户:[]数组而不是对象用户:{},因此上述结果不够好,则可以使用以下方法

{  
  $project: {
    _id: 1,
    description: 1,
    title: 1,
    user: {
      $let: {
        vars: {
          firstUser: {
            $arrayElemAt: ["$user", 0]
          }
        },
        in: {
          name: "$$firstUser.name",
          email: "$$firstUser.email"
        }
      }
    }
  }
}

如果用户对象有更多的字段(如电子邮件),该怎么办?我可以这样添加它:{project:{u id:1,description:1,title:1,“user.name”:{$arrayElemAt:[“$user.name”,0]},“user.email”:{$arrayElemAt:[“$user.email”,0]},应该可以用。但我也更新了答案,以反映一种稍微不同的方法。这个解决方案实际上不是以对象的形式返回用户,而是以大小为1的数组的形式返回用户。所以有一个用户:[{name:“name”,email:“email”}]。你知道我怎么解决这个问题吗?我可以在前端做,但我认为在后端做会更好。是的,你可以使用。这应该能帮你完成任务。基本上,它会创建一个临时变量供您使用。谢谢您,阿明,我非常感谢您的帮助。