我有一个包含以下字段的文档:
...
firebaseTokens: { type: Map, of: String },
androidIds: [{ type: String, maxlength: 128 }],
advertisingIds: [{ type: String, maxlength: 128 }],
firebaseInstallationIds: [{ type: String, maxlength: 128 }],
...
当我想在一次操作中同时使用
$AddToSet
设置所有三个数组时,仅设置最后一个数组。
let user = {
_id: userId,
$set: { [`firebaseTokens.${deviceId}`]: token, },
$addToSet: { androidIds: deviceId },
$addToSet: { advertisingIds: advertisingId },
$addToSet: { firebaseInstallationIds: firebaseInstallationId }
}
let options = { new: true, setDefaultsOnInsert: true };
let userDoc = await UserModel.findByIdAndUpdate(user._id, user, options);
上面的代码中,只设置了firebaseInstallationIds。
您遇到的问题是由于更新对象中的
$addToSet
操作的结构方式造成的。在 JavaScript 中,当您定义具有多个具有相同键的属性的对象时,最后一个属性将覆盖所有具有相同键的先前属性。这就是为什么只设置 firebaseInstallationIds
;这是对象中最后一个 $addToSet
操作。
要纠正此问题,您需要将所有
$addToSet
操作合并到一个对象中。
这是工作示例:
let user = {
_id: userId,
$set: { [`firebaseTokens.${deviceId}`]: token },
$addToSet: {
androidIds: deviceId,
advertisingIds: advertisingId,
firebaseInstallationIds: firebaseInstallationId
}
}
let options = { new: true, setDefaultsOnInsert: true };
let userDoc = await UserModel.findByIdAndUpdate(user._id, user, options);