node.js - 一对多 Mongoose 关系 - 在哪里存储引用

标签 node.js mongodb mongoose mongodb-query mongoose-schema

我正在为一个新项目设计 MongoDB 集合架构,作为 MongoDB 的新手,我有一个关于一对多关系的问题。

为了这个例子,假设关系是Datacenter-to-Servers,这意味着一个Datacenter可以有多个服务器(数千个,不限于应用程序),并且这些服务器只能属于一个Datacenter。

最好让 Servers._datacenter 引用 Datacenter._id 吗?还是一个Datacenter.servers array 来存储服务器ID?

如果您建议在数据中心文档中使用数组 来引用与之相关联的服务器 ID... 那么有没有一种方法可以在您拥有时找出服务器属于哪个数据中心服务器ID? (有点像快速的 where serverId in Datacenter.servers 查询)而不必查询每个数据中心,然后检查每个 Datacenter.servers 数组中的 ID

如果您建议在服务器文档中使用一个元素来引用它所属的数据中心,那么有没有办法查询数据中心,并在虚拟 Documents.servers 数组或其他内容中返回所有关联的服务器文档?

我不太确定最佳路线是什么,因为每个数据中心可能有非常大量的服务器,我认为最好不要在每个数据中心文档中包含这么大的数组。 .. 但是如果我设置它以便每个服务器文档都在其中引用父数据中心,这会使查询变得相当困难(或者不是?也许有一种我还没有发现的非常简单的方法,我确实说过我是Mongo 的新手)

我正在通读 this document ,它显示了如何以任何一种方式设置引用方向,并指出:

To avoid mutable, growing arrays, store the publisher reference inside the book document

所以我认为最好在服务器文档中引用数据中心 ID。如果是这样的话,有没有办法将所有服务器文档作为数据中心文档中的数组返回?或者我是否必须查询数据中心,然后查询具有该数据中心的所有服务器。_id,然后返回合并的对象..

最佳答案

这取决于访问模式。如 null1941 所说,您打算如何对此进行编码。

如果服务器的数量是 10 台或数百台,我想那将是一对多的关系,而不是一对多的关系,因此您可以继续将数据中心嵌入到服务器中。这意味着您将通过一次查询一次性获得所需的所有信息。 如果您可以保证一致性,这种方法可能会奏效,但如果一个数据中心中存在许多服务器,您最终会出现重复。因此数据中心文件可以复制到许多服务器文件中。如果你能再次保证一致性并且数据中心可能没有关于它们的信息,这种方法就可以工作。这种方法的唯一优点是您只进行一次查询。 通常不推荐这种方法;此外,如果您想将数据中心视为一个单独的文档,以便在其上运行一些操作,而不是避免这种方法。

如果您决定采用这种方法;将数据中心作为数组嵌入您可以使用 $all$in 在数组内搜索。

例子:

{
"_id" : ObjectId("63546464sad65s4ad3654"),
"name" : "Server1",
"datacenter" : ["gamma", "500"]          

}

查询:

db.users.find({ "datacenter": { $in: [ "gamma", "delta" ] } } )

如果您决定将服务器作为文档嵌入(您也可以将数据中心文档嵌入到服务器中,两者都可以)。因此,对于在数据中心文档中嵌入服务器,您可以使用点符号在嵌入文档中搜索。示例:(服务器是字典,名称是服务器内部的一个属性):

{
"_id" : ObjectId("63546464sad65s4ad3654"),
"name" : "gamma",
"servers" : [
            {
              "title" : "server1",
              "speed" : "3.2GHZ",
              "ram"   : "200GB"
            },
            {
              "title" : "server2",
              "speed" : "3.2GHZ",
              "ram"   : "64GB"
            }
         ]
}

查询:

db.datacenters.find( { "servers.title": "server1" } 

再次判断。但是,您决定这样做,mongodb 中有一种方法可以检索您需要的信息。

现在请记住,如果您决定在数据中心文档中嵌入服务器,那么在 mongodb 中单个文档不应超过 16MB。如果通过嵌入可能会超过此大小,您应该采用拆分方法(如下)。

现在更好的方法嵌入的情况;基本上正如gnerkus所说。但是请记住,mongodb 中没有外键约束,您必须确保使用应用程序的一致性。这样数据中心集合中的 server_id 可以在服务器集合中找到(反之亦然)。您还可以将 datacenter_id 放在服务器集合中;我决定选择哪一个的方式是我的用例。例如,如果我的大部分操作都在数据中心上,我将向其添加 server_id。如果我的大部分操作都在服务器集合上,我将向其添加 datacenter_id。在这两种情况下,您都将执行两个或多个查询。这是一个例子:

数据中心文档示例

 {
     _id : ObjectId("10001000010000"),
     name : 'Gamma',        
     location: 'pluto',
     servers: [      
         ObjectID('1212'),     
         ObjectID('1213') 
              ]    
 }

服务器文档示例:

{
    _id : ObjectId("1212"),
    name : 'Server1',
    ram: '250GB',
    type: 'processing',
    status: 'running' 
}

在这种情况下,您可以这样查询:首先您获得所需的数据中心(假设名称是唯一的)

datacenter = db.datacenter.findOne({name: "Gamma"})

然后您将查询所需服务器的详细信息;获取上面给定数据中心中所有服务器的示例

servers = db.servers.find({_id: { $in : datacenter.servers } } )

在您拥有所有服务器之后,您可以遍历每个服务器并检查状态或其他内容。您最终会将服务器文档保存在服务器变量中。

希望对你有帮助

关于node.js - 一对多 Mongoose 关系 - 在哪里存储引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34999422/

相关文章:

javascript - 前端的 new Date() 格式与后端的 new Date() 格式不同

javascript - Node.js,Express : Cannot set headers after they are sent to the client

javascript - Mongoose,将 `.aggregate()` 应用于子文档数组,并以最少的查询次数获得文档其他字段的结果

javascript - 澄清 Mockgoose/Mongoose 的用法?

javascript - 为什么这个node-mysql插入会产生一个数组?

node.js - 使用 Mongoose 将文档嵌入表单中

node.js - Electron/Angular2/打字应用程序 : Import module in a component

javascript - Mongoose 无法从 MongoDB 数据库获取数据

MongoDB 复合索引

mongodb - 我如何在 Ubuntu 上安装 MongoDb 并在安装时设置配置