[英]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.