需要建议在 mongodb 中使用 mongoose 设计数据库

Posted

技术标签:

【中文标题】需要建议在 mongodb 中使用 mongoose 设计数据库【英文标题】:Need advice to design database in mongodb with mongoose 【发布时间】:2020-04-22 06:11:12 【问题描述】:

我有 2 个集合:Hospital 和 Patient。 这个月病人在A医院检查,下个月这个病人在B医院检查。那么在更新病人信息的时候,如何保存病人已经在A医院检查的病历呢?请给我一个建议?谢谢

【问题讨论】:

将其另存为单独的集合,称为咨询。有两个不同时间戳的两次访问的单独记录。 【参考方案1】:

为此,您需要有一个单独的检查集合。 (它就像关系数据库中的中间(关联)表。)

解决此问题的一种方法是使用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"

现在有了这些知识,您可以自己从医院方面实施检索操作。

【讨论】:

非常感谢。你拯救了我的一天。太好了 @cauchuyennhocuatoi 欢迎您。您可以标记为答案并投票吗? ***.com/help/someone-answers 亲爱的@SuleymanSah:抱歉因为周末回复晚了,我已经标记了你的答案,非常感谢【参考方案2】:

Mongodb 不允许像基于 sql 的数据库这样的特定连接。我建议根据需要创建您的医院集合模式(很可能只是基本类型,如字符串和数字),然后存储带有日期和位置的访问或检查列表作为患者模式的一部分(请参阅:https://mongoosejs.com/docs/schematypes.html#arrays) .虽然您无法在数据库级别强制要求检查地点是一家有效的医院,但您当然可以在代码中强制执行。

【讨论】:

以上是关于需要建议在 mongodb 中使用 mongoose 设计数据库的主要内容,如果未能解决你的问题,请参考以下文章

Node中使用MongoDB

PostgreSQL 相当于 MongoDB 的 Mongoose?

在codeigniter mongodb中插入函数的位置

需要建议在 mongodb 中使用 mongoose 设计数据库

需要建议在 mongodb 中使用 mongoose 设计数据库

Moogose的基本连接以及增删改查操作