[英]How to bulk execute two updates on the same field?
我从数组中提取一个值并立即将其添加回数组的前面。
await User.findByIdAndUpdate(authenticatedUserId,
{ $pull: { lastVisitedResources: resourceId } },
).exec();
await User.findByIdAndUpdate(authenticatedUserId,
{ $push: { lastVisitedResources: { $each: [resourceId], $position: 0, $slice: -50 } } },
).exec();
有没有办法通过批量操作更有效地执行此操作? 我尝试了Mongoose 的 bulkWrite以及 MongoDB 的较低级别的db.collection.bulkWrite但 TypeScript 不接受其中任何一个的$pull
和$push
运算符:
await User.bulkWrite([
{
updateOne: {
filter: { _id: authenticatedUserId },
update: {
$pull: { lastVisitedResources: resourceId }
}
}
},
{
updateOne: {
filter: { _id: authenticatedUserId },
update: {
$push: { lastVisitedResources: { $each: [resourceId], $position: 0, $slice: 50 } }
}
}
}
])
打印以下错误:
Type '{ lastVisitedResources: string; }' is not assignable to type 'PullOperator<Document>'.
Type '{ lastVisitedResources: string; }' is not assignable to type '{ readonly [x: string]: Partial<any> | { [x: string]: FilterOperators<any> | undefined; } | FilterOperators<any> | undefined; }'.
Property 'lastVisitedResources' is incompatible with index signature.
Type 'string' is not assignable to type 'Partial<any> | { [x: string]: FilterOperators<any> | undefined; } | FilterOperators<any> | undefined'.ts(2322)
我也试过initializeOrderedBulkOp
但它没有效果:
const bulk = User.collection.initializeOrderedBulkOp();
bulk.find({ _id: authenticatedUserId })
.updateOne({ $pull: { lastVisitedResources: resourceId } });
bulk.find({ _id: authenticatedUserId })
.updateOne({ $push: { lastVisitedResources: { $each: [resourceId], $position: 0, $slice: -50 } } });
await bulk.execute();
您可以使用聚合管道更新语法,如下所示:
User.findByIdAndUpdate(authenticatedUserId,
[
{
$set: {
lastVisitedResources: {
$slice: [
{
$concatArrays: [
[
resourceId
],
{
$filter: {
input: {
$ifNull: [
"$lastVisitedResources",
[]
]
},
cond: {
$ne: [
"$$this",
resourceId
]
}
}
}
]
},
50
]
}
}
}
])
事实证明,这实际上是 TypeScript 的误报。 按照@Tom Slabbaert 的建议,我在$push
和$pull
运算符中添加了ts-ignore
并且它可以正常工作:
await User.bulkWrite([
{
updateOne: {
filter: { _id: authenticatedUserId },
update: {
// @ts-ignore
$pull: { lastVisitedResources: resourceId }
}
}
},
{
updateOne: {
filter: { _id: authenticatedUserId },
update: {
// @ts-ignore
$push: { lastVisitedResources: { $each: [resourceId], $position: 0, $slice: 50 } }
}
}
}
])
注意:如果您使用本机db.collection.bulkWrite
而不是 Mongoose 的Model.bulkWrite
,则必须将id
从string
s 转换为mongoose.Type.ObjectId
s。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.