【发布时间】:2020-04-22 06:11:12
【问题描述】:
我有 2 个集合:Hospital 和 Patient。 这个月病人在A医院检查,下个月这个病人在B医院检查。那么在更新病人信息的时候,如何保存病人已经在A医院检查的病历呢?请给我一个建议?谢谢
【问题讨论】:
-
将其另存为单独的集合,称为咨询。有两个不同时间戳的两次访问的单独记录。
标签: node.js mongodb express mongoose
我有 2 个集合:Hospital 和 Patient。 这个月病人在A医院检查,下个月这个病人在B医院检查。那么在更新病人信息的时候,如何保存病人已经在A医院检查的病历呢?请给我一个建议?谢谢
【问题讨论】:
标签: node.js mongodb express mongoose
为此,您需要有一个单独的检查集合。 (它就像关系数据库中的中间(关联)表。)
解决此问题的一种方法是使用virtual populate。 使用虚拟填充,我们不需要保留对考试的引用,这将在添加、更新或删除考试时简化事情。 因为只有考试集合需要更新。
耐心.js
const mongoose = require("mongoose");
const patientSchema = new mongoose.Schema(
{
name: String
},
{
toJSON: { virtuals: true }
}
);
// Virtual populate
patientSchema.virtual("examinations", {
ref: "Examination",
foreignField: "patientId",
localField: "_id"
});
module.exports = mongoose.model("Patient", patientSchema);
医院.js
const mongoose = require("mongoose");
const hospitalSchema = new mongoose.Schema(
{
name: String
},
{
toJSON: { virtuals: true }
}
);
// Virtual populate
hospitalSchema.virtual("examinations", {
ref: "Examination",
foreignField: "hospitalId",
localField: "_id"
});
module.exports = mongoose.model("Hospital", hospitalSchema);
examination.js
const mongoose = require("mongoose");
const examinationSchema = new mongoose.Schema({
when: {
type: Date,
default: Date.now()
},
patientId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Patient"
},
hospitalId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Hospital"
}
});
module.exports = mongoose.model("Examination", examinationSchema);
如您所见,我们的患者和医院架构非常简洁,没有任何检查参考。
让我们有这些现有的病人。
{
"_id" : ObjectId("5e0f86d0ea3eb831a4845064"),
"name" : "Patient 1",
"__v" : NumberInt(0)
},
{
"_id" : ObjectId("5e0f86dbea3eb831a4845065"),
"name" : "Patient 2",
"__v" : NumberInt(0)
}
让我们拥有这些现有的医院。
{
"_id" : ObjectId("5e0f86feea3eb831a4845066"),
"name" : "Hospital 1",
"__v" : NumberInt(0)
},
{
"_id" : ObjectId("5e0f8705ea3eb831a4845067"),
"name" : "Hospital 2",
"__v" : NumberInt(0)
}
让我们进行这些现有的检查。
/* Patient 1 - Hospital 1 */
{
"when": "2020-01-03T18:27:12.997Z",
"_id": "5e0f878346e50d41d846d482",
"patientId": "5e0f86d0ea3eb831a4845064",
"hospitalId": "5e0f86feea3eb831a4845066",
"__v": 0
},
/* Patient 1 - Hospital 1 */
{
"when": "2020-01-03T18:27:12.997Z",
"_id": "5e0f87a646e50d41d846d483",
"patientId": "5e0f86d0ea3eb831a4845064",
"hospitalId": "5e0f86feea3eb831a4845066",
"__v": 0
},
/* Patient 1 - Hospital 2*/
{
"when": "2020-01-03T18:27:12.997Z",
"_id": "5e0f87c446e50d41d846d484",
"patientId": "5e0f86d0ea3eb831a4845064",
"hospitalId": "5e0f8705ea3eb831a4845067",
"__v": 0
},
/* Patient 2 - Hospital 1 */
{
"when": "2020-01-03T18:27:12.997Z",
"_id": "5e0f87e046e50d41d846d485",
"patientId": "5e0f86dbea3eb831a4845065",
"hospitalId": "5e0f86feea3eb831a4845066",
"__v": 0
}
现在,如果我们想获取患者的信息和他/她的检查,我们可以使用以下代码:
app.get("/patients/:id", async (req, res) => {
const result = await Patient.findById(req.params.id).populate("examinations");
res.send(result);
});
结果会是这样的:
{
"_id": "5e0f86d0ea3eb831a4845064",
"name": "Patient 1",
"__v": 0,
"examinations": [
{
"when": "2020-01-03T18:27:12.997Z",
"_id": "5e0f878346e50d41d846d482",
"patientId": "5e0f86d0ea3eb831a4845064",
"hospitalId": "5e0f86feea3eb831a4845066",
"__v": 0
},
{
"when": "2020-01-03T18:27:12.997Z",
"_id": "5e0f87a646e50d41d846d483",
"patientId": "5e0f86d0ea3eb831a4845064",
"hospitalId": "5e0f86feea3eb831a4845066",
"__v": 0
},
{
"when": "2020-01-03T18:27:12.997Z",
"_id": "5e0f87c446e50d41d846d484",
"patientId": "5e0f86d0ea3eb831a4845064",
"hospitalId": "5e0f8705ea3eb831a4845067",
"__v": 0
}
],
"id": "5e0f86d0ea3eb831a4845064"
}
我们甚至可以像这样使用内部填充来填充医院:
app.get("/patients/:id", async (req, res) => {
const result = await Patient.findById(req.params.id).populate({
path: "examinations",
populate: {
path: "hospitalId"
}
});
res.send(result);
});
结果将包含医院信息:
{
"_id": "5e0f86d0ea3eb831a4845064",
"name": "Patient 1",
"__v": 0,
"examinations": [
{
"when": "2020-01-03T18:27:12.997Z",
"_id": "5e0f878346e50d41d846d482",
"patientId": "5e0f86d0ea3eb831a4845064",
"hospitalId": {
"_id": "5e0f86feea3eb831a4845066",
"name": "Hospital 1",
"__v": 0,
"id": "5e0f86feea3eb831a4845066"
},
"__v": 0
},
{
"when": "2020-01-03T18:27:12.997Z",
"_id": "5e0f87a646e50d41d846d483",
"patientId": "5e0f86d0ea3eb831a4845064",
"hospitalId": {
"_id": "5e0f86feea3eb831a4845066",
"name": "Hospital 1",
"__v": 0,
"id": "5e0f86feea3eb831a4845066"
},
"__v": 0
},
{
"when": "2020-01-03T18:27:12.997Z",
"_id": "5e0f87c446e50d41d846d484",
"patientId": "5e0f86d0ea3eb831a4845064",
"hospitalId": {
"_id": "5e0f8705ea3eb831a4845067",
"name": "Hospital 2",
"__v": 0,
"id": "5e0f8705ea3eb831a4845067"
},
"__v": 0
}
],
"id": "5e0f86d0ea3eb831a4845064"
}
现在有了这些知识,您可以自己从医院方面实施检索操作。
【讨论】:
Mongodb 不允许像基于 sql 的数据库这样的特定连接。我建议根据需要创建您的医院集合模式(很可能只是基本类型,如字符串和数字),然后存储带有日期和位置的访问或检查列表作为患者模式的一部分(请参阅:https://mongoosejs.com/docs/schematypes.html#arrays) .虽然您无法在数据库级别强制要求检查地点是一家有效的医院,但您当然可以在代码中强制执行。
【讨论】: