在事务期间如何从MongoDB创建操作中检索ID?

问题描述

我正在尝试使用Apollo Server和Mongoose创建审核跟踪。当用户最初注册时,我在用户集合中为他们提供的每条数据(用户名,密码,电子邮件等)创建一个文档,并在历史记录集合中创建一个文档。对于每个历史记录收集文档,我都包含用于创建关系的用户文档的ID。完美运行。

但是,当我在其中添加事务时(见下文),该用户文档的userId会以未定义的形式返回,因此我无法将其添加到历史记录条目文档中。我假设在完成整个交易之前不会创建文档的ID?

有什么想法吗?

Mutation: {
  register: async (_,{ data }) => {

    // Start a mongo session & transaction
    const session = await mongoose.startSession()
    session.startTransaction()

    try {

      // Hash password and create user
      const hashedPassword = await bcrypt.hash(data.password,12)
      const user = await User.create(
        [{ ...data,password: hashedPassword }],{ session }
      )
      
      // Add history entries
      HistoryEntry.create([
      {
        user: user.id,action: 'registered'
      },{
        user: user.id,action: 'set',object: 'profile',instance: user.id,property: 'firstName',value: firstName
      },property: 'lastName',value: lastName
      },property: 'password'
      }
    ])

    if (loginType === 'email') {
      HistoryEntry.create({
        user: user.id,property: 'email',value: login
      })
    }

    if (loginType === 'mobile') {
      HistoryEntry.create({
        user: user.id,property: 'mobile',value: login
      })
    }

    // commit the changes if everything was successful
    await session.commitTransaction()
      return {
        ok: true,user
      }
    } catch (err) {
      // if anything fails above,rollback the changes in the transaction
      await session.abortTransaction()
      return formatErrors(err)
    } finally {
      // end the session
      session.endSession()
    }
  }
}

解决方法

考虑一下,如果还没有添加用户,如何添加HistoryEntry?这不是您当前正在做的“历史”。我相信您在这里有两个选择-在用户new Schema({ _id: { type: Schema.ObjectId,auto: true }})上手动设置_id,然后在事务中生成它:var userId = ObjectId();并用于用户和历史条目。

第二种选择,我认为在这种情况下在语义上更正确-您应该附加到post-save hook

schema.post('save',function(doc) {
  console.log('%s has been saved',doc._id);
});

因此,每当创建用户时,都会触发保存后的钩子以更新历史记录。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...