簡體   English   中英

如何在同一字段上批量執行兩次更新?

[英]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 ,則必須將idstring s 轉換為mongoose.Type.ObjectId s。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM