[英]What is the best way to keep track of changes of a document's property in MongoDB?
我想知道如何在MongoDB中跟踪文档的值。
这是一个具有Node和Express后端的MongoDB数据库。
假设我有一个文档,它是患者集合的一部分。
{
"_id": "4k2lK49938d82kL",
"firstName": "John",
"objective": "Burn fat"
}
然后,我编辑“ objective”属性,因此文档结果如下:
{
"_id": "4k2lK49938d82kL",
"firstName": "John",
"objective": "Gain muscle"
}
跟踪更改的最佳/最有效方法是什么? 换句话说,我想知道“客观”属性在过去具有“燃烧脂肪”的值,并在将来使用它。
非常感谢!
将其维护为如下所示的子文档
{
"_id": "4k2lK49938d82kL",
"firstName": "John",
"objective": {
obj1: "Gain muscle",
obj2: "Burn fat"
}
}
您也可以将其维护为数组字段,但是请记住,mongodb不允许您在数组字段中保持唯一性,并且如果您计划对“ objective”字段建立索引,则必须创建一个多键索引
也许您可以将“目标”的类型更改为数组并跟踪其中的更改。 数组的最后一个是最新值。
我认为最简单的解决方案是使用和更新数组:
const patientSchema = new Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
objective: { type: String, required: true }
notes: [{
date: { type: Date, default: Date.now() },
note: { type: String, required: true }
}],
});
然后,当您要更新目标时...
const updatePatientObjective = async (req, res) => {
try {
// check if _id and new objective exist in req.body
const { _id, objective, date } = req.body;
if (!_id || !objective) throw "Unable to update patient's objective.";
// make sure provided _id is valid
const existingPatient = await Patient.findOne({ _id });
if (!existingPatient) throw "Unable to locate that patient.";
// pull out objective as previousObjective
const { objective: previousObjective } = existingPatient;
// update patient's objective while pushing
// the previous objective into the notes sub document
await existingPatient.updateOne({
// update current objective
$set { objective },
// push an object with a date and note (previouseObjective)
// into a notes array
$push: {
notes: {
date,
note: previousObjective
},
},
}),
);
// send back response
res
.status(201)
.json({ message: "Successfully updated your objective!" });
} catch (err) {
return res.status(400).json({ err: err.toString() });
}
};
文档将如下所示:
firstName: "John",
lastName: "Smith",
objective: "Lose body fat.",
notes: [
{
date: 2019-07-19T17:45:43-07:00,
note: "Gain muscle".
},
{
date: 2019-08-09T12:00:38-07:00,
note: "Work on cardio."
}
{
date: 2019-08-29T19:00:38-07:00,
note: "Become a fullstack web developer."
}
...etc
]
另外,如果您担心文档的大小,则可以为患者历史记录创建一个单独的架构,并引用用户的ID(或仅将患者的_id存储为字符串,而不是引用ObjectId,这取决于您的偏好):
const patientHistorySchema = new Schema({
_id: { type: Schema.Types.ObjectId, ref: "Patient", required: true },
objective: { type: String, required: true }
});
然后在目标更新时创建一个新的患者历史记录文档...
PatientHistory.create({ _id, objective: previousObjective });
如果您需要访问病史文档...
PatientHistory.find({ _id });
不建议在同一文档中维护/跟踪历史记录。 随着文档大小的不断增加,导致
相反,您应该为历史记录维护一个单独的集合。 您可能使用过休眠的Javers或envers来审核关系数据库。 如果没有,您可以检查它们的工作方式。 每个表(xyz)维护一个单独的表(xyz_AUD)。 对于xyz表中的每一行(具有主键abc),xyz_AUD表中都存在多行,其中每一行都是该行的版本。
此外,Javers还支持MongoDB审核。 如果您使用的是Java,则可以直接使用它。 无需编写自己的逻辑。
请参阅-https: //nullbeans.com/auditing-using-spring-boot-mongodb-and-javers/
Javers Envers Hibernate是Java库。 但我敢肯定,对于其他编程语言,也会有类似的库。
还有一个猫鼬插件-
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.