猫鼬查询可根据嵌套字段过滤集合

时间:2020-10-30 20:16:35

标签: node.js mongoose mongoose-schema

我们想知道猫鼬是否可以通过繁重的工作来获得给定组织名称和用户ID的用户角色。

先找到组织数据并使用javascript根据用户ID进行过滤,即可轻松完成此操作。但是我认为,如果查询能够做到这一点而不是在mongo集合之外进行,它将提供更好的性能。

我们想尝试如下所示的方法,但是它没有正确赋予用户角色。

查询(不起作用)

    public async getUserOrgRole(orgName: string, userId) {
        const result = await this.organizationModel
            .findOne({ name: orgName, 'orgMembers.userId': userId })
            .select('orgMembers.role')
            .exec();
        if (result) {
            const orgMember = _.get(result, 'orgMembers');
            return orgMember[0].role;
        }
        return null;
    }

查询(可以,但是我们希望上面的查询可以正常工作,而不是提取整个文档)

    public async getUserOrgRole(orgName: string, userId) {
        const org = await this.organizationModel.findOne({ name: orgName })
        if (!org)
            return null;
        const userInOrg = org.orgMembers.find(om => om.userId === userId)
        console.log('--getUserOrgRole', userInOrg)
        if (userInOrg)
            return userInOrg.role
        return null;
    }



模式


const UserOrgSchema = new Schema({
    role: { type: Schema.Types.String, enum: ['MEMBER', 'OWNER', 'ADMIN'], default: 'MEMBER' },
    inactive: { type: Schema.Types.Boolean, default: false },
    userId: { type: Schema.Types.String, required: true },
});


const OrganizationSchema = new Schema({
    name: { type: Schema.Types.String, unique: true },
    picture: { type: Schema.Types.String },
    orgMembers: { type: [UserOrgSchema] },
    createdAt: { type: Schema.Types.Date, default: Date.now },
    updatedAt: { type: Schema.Types.Date, default: Date.now },
});

1 个答案:

答案 0 :(得分:0)

您几乎完全正确。 Sunil解释了您的尝试无法奏效的原因。无论您将什么过滤器应用于.find(),它都将始终返回整个文档。如果要选择特定的子文档,则需要使用附加的select运算符。这应该起作用:

const result = await this.organizationModel
  .findOne({ name: orgName, "orgMembers.userId": userId })
  .select({
    orgMembers: {
      $elemMatch: {
        userId,
      },
    },
  })
  .select("orgMembers.role")
  .exec();

请注意使用$elemMatch!它完全满足您的要求-通过仅选择与提供的过滤器匹配的子文档来过滤子文档。