因此,我試圖通過更新 sub-array 中的元素來向 MongoDB 存盤發出 PATCH 請求。這是資料的樣子:
const booksSchema = mongoose.Schema(
{
name: { type: String, trim: true },
author: { type: String, trim: true },
},
{ timestamps: true },
)
const Book = mongoose.model('Book', bookSchema)
const librarySchema = mongoose.Schema(
{ books: [ Books.schema ] },
{ timestamps: true },
)
const Library = mongoose.model('Library', librarySchema)
這就是我更新資料的方式:
const library = await Library.findOneAndUpdate(
{ _id: libraryId, "books._id": bookId },
{ $set: { "books.$": bookBody } },
)
在此程序中,我遇到了與 $set 命令沖突的自動時間戳更新問題:
Updating the path 'books.$.updatedAt' would create a conflict at 'books.$'
我遇到的在不洗掉自動時間戳更新的情況下進行此類更新的最佳解決方案是手動設定每個欄位,如下所示:
const library = await Library.findOneAndUpdate(
{ _id: libraryId, "book._id": bookId },
{
$set: {
"book.$.name": bookBody.name,
"book.$.author": bookBody.author,
}
},
)
...但是這個解決方案非常冗長。
有沒有一種更優雅的方式來執行這種型別的 PATCH 請求,也許使用某種物件解構,而不需要維護每個欄位的映射?
uj5u.com熱心網友回復:
事實上,如果您的意圖是按照 HTTP 協議中描述的方式執行 PATCH 操作:
HTTP PATCH 請求方法將部分修改應用于資源。
來源:https ://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH
在您的情況下,您應該使用“詳細”解決方案,因為您的替代更新{ $set: { "books.$": bookBody } }將從更新的書中洗掉更新中缺少的任何屬性。這不是 PATCH 的作業方式,而是 PUT 的作業方式。
您可以通過引入執行類似這樣的輔助函式(示例使用 lodash)來使您的代碼不那么冗長:
import _ from 'lodash'
_.mapValues(book, (value) => {
_.mapKeys(value, (innerValue, innerKey) => (
`book.$.${innerKey}`
)
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/423997.html
