我正在更新具有特定 _id 的角色的年齡和姓名,該角色來自模型 Drama 檔案中的一組字符。
我正在處理的檔案:-
{
"_id" : ObjectId("619d44d2ec2ca20ca0404b5a"),
"characters" : [
{
"_id" : ObjectId("619fdac5a03c8b10d0b8b13c"),
"age" : "23",
"name" : "Vinay",
},
{
"_id" : ObjectId("619fe1d53810a130207a409d"),
"age" : "25",
"name" : "Raghu",
},
{
"_id" : ObjectId("619fe1d53810a130207a502v"),
"age" : "27",
"name" : "Teju",
}
],
}
因此,為了更新角色 Raghu,我這樣做了:-
const characterObj = {
age: "26",
name: "Dr. Raghu",
};
Drama.updateOne(
{ _id: req.drama._id, "characters._id": characterId },
{
$set: {
"characters.$": characterObj,
},
},
function(err, foundlist) {
if (err) {
console.log(err);
} else {
console.log("Update completed");
}
}
);
// req.drama._id is ObjectId("619d44d2ec2ca20ca0404b5a")
// characterId is ObjectId("619fe1d53810a130207a409d")
這更新了角色,但它也為角色的 _id 欄位分配了一個新的 ObjectId。所以,我正在尋找如何防止 _id update 的方法。
另外,我知道我可以設定角色的各個欄位,而不是分配一個全新的物件來防止這種情況發生,但是如果我的角色的物件有很多欄位,那將非常乏味。
//Not looking to do it this way
$set: {
"characters.$.age": characterObj.age,
"characters.$.name": characterObj.name,
},
謝謝。
uj5u.com熱心網友回復:
我在這里找到了一些東西,只需預先定義一個影響 id 的模式(某種方式的藍圖)
var subSchema = mongoose.Schema({
//your subschema content
},{ _id : false });
阻止 Mongoose 為子檔案陣列項創建 _id 屬性
或者我會說,當您創建一個角色時,從一開始就為其分配一個自定義 id,這樣它就會始終保留該 id。
uj5u.com熱心網友回復:
我將這個問題懸而未決,因為我仍然希望看到一種更簡單的方法。但就目前而言,我確實為這個問題找到了一個簡單的替代解決方案,我將在一段時間內使用它,直到找到更直接的方法。
簡而言之 - 使用lodash在舊物件中深度合并新物件,然后使用新合并的物件設定欄位值。
例如,讓我們更新我的問題檔案中的角色 Raghu:-
- 首先使用 npm 安裝 lodash(深度合并物件需要):
$ npm i -g npm
$ npm i --save lodash
- 匯入 lodash:
const _ = require("lodash");
- 現在像這樣更新角色 Raghu:-
const newCharacterObj = {
age: "26",
name: "Dr. Raghu",
};
Drama.findById(
{ _id: req.drama._id, "characters._id": characterId },
"characters.$",
function(err, dramaDocWithSpecificCharacter) {
console.log(dramaDocWithSpecificCharacter);
// ↓↓↓ console would log ↓↓↓
// {
// "_id" : ObjectId("619d44d2ec2ca20ca0404b5a"),
// "characters" : [
// {
// "_id" : ObjectId("619fe1d53810a130207a409d"),
// "age" : "25",
// "name" : "Raghu",
// }
// ],
// }
const oldCharacterObj = dramaDocWithSpecificCharacter.characters[0];
const mergedCharacterObjs = _.merge(oldCharacterObj, newCharacterObj);
// _.merge() returns a deep merged object
console.log(mergedCharacterObjs);
// ↓↓↓ console would log ↓↓↓
// {
// _id: 619fe1d53810a130207a409d,
// age: "26",
// name: "Dr. Raghu",
// };
Drama.updateOne(
{ _id: req.drama._id, "characters._id": characterId },
{
$set: {
"characters.$": mergedCharacterObjs,
},
},
function(err, foundlist) {
if (err) {
console.log(err);
} else {
console.log("Update completed");
}
}
);
}
);
// req.drama._id is ObjectId("619d44d2ec2ca20ca0404b5a")
// characterId is ObjectId("619fe1d53810a130207a409d")
注意:我們也可以使用本機Object.assign()or …(擴展運算子)來合并物件,但它的缺點是它不合并嵌套物件,如果您以后決定添加嵌套物件而不對深度合并進行更改,這可能會導致問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/367649.html
