简体   繁体   English

如何填充不相关的字段猫鼬

[英]How to populate a non related field mongoose

Document Role = 文件角色=

{ "_id" = "12345",  
   Name = "Developer"
},

{ "_id" = "67890",  
   Name = "Manager"
}

Document Employee = 凭证员工=

{ "_id" = "00000",
  "Name"= "Jack",
  "Roles"= [{_id:"12345"},{_id:"67890"}]
}

I want to select one Role and list all the users having the same role How to do that? 我想选择一个角色并列出所有具有相同角色的用户。

I want to get some thing like. 我想得到一些类似的东西。

{ "_id" = "12345",  
   Name = "Developer"
   Employees = [{"_id":"00000"}]
}

Is it possible to use populate to achieve this? 是否可以使用填充来实现这一目标?

Mongoose .populate() and other methods you might find are not "join magic" for MongoDB. Mongoose .populate()和您可能会发现的其他方法不是MongoDB的“加入魔术”。 What they in fact all do is execute "additional" query(ies) operations on the database and "merge" the results "under the hood" for your as opposed to you doing the work yourself. 他们其实都是要做的就是在数据库上执行“附加”查询(一个或多个)操作和“合并”结果“引擎盖下”为你而不是你做自己的工作。

So your best option as long as you can deal with it is to use "embedding" which keeps the "related" information in the document for which you are "pairing" it to, such as for "Roles": 因此,您最好的选择就是使用“嵌入”,将“相关”信息保留在您要与之“配对”的文档中,例如“角色”:

{
    "_id": "0000",
    "name": "Developer",
    "employees": [{ "_id": "12345", "name": "Jack" }]
}

Which is simple, but of course comes at it's own cost and dealing with the "embedded" entries and how you use it according to "updating" or "reading" as is appropriate. 这很简单,但是当然要自负费用,并且要适当地处理“嵌入”条目以及如何根据“更新”或“阅读”使用它。 It's a single "read" operation, but "updates" may be more costly due to the need to update the embedded information in multiple places, and multiple documents. 这是一次“读取”操作,但是由于需要在多个位置和多个文档中更新嵌入的信息,因此“更新”的成本可能更高。

If you can "live" with "referencing" and the cost it incurs then you can always do this: 如果您可以“参考”“生活”及其产生的费用,那么您始终可以这样做:

var rolesSchema = Schema({
    "name": String,
    "emloyees": [{ "type": Schema.Types.ObjectId, "ref": "Employee" }]
});

var employeesSchema = Schema({
    "name": String,
    "roles": [{ "type": Schema.Types.ObjectId, "ref": "Role" }]
});

var Role = mongoose.model('Role',rolesSchema); var Role = mongoose.model('Role',rolesSchema); var Employee = mongoose.model('Employee',employeeSchema); var Employee = mongoose.model('Employee',employeeSchema);

Role.find({ "_id": "12345"}).populate("employees").exec(function(err,docs) { // populated "joined" results in here }) Role.find({“ _id”:“ 12345”})。populate(“ employees”)。exec(function(err,docs){//在此处填充“ joined”结果})

What this does behind the scenes is effectively (basic JavaScript representation and "at best") : 这实际上是在幕后做的(基本的JavaScript表示形式,“充其量”):

var roles = db.role.find({ "_id": "12345" }).map(function(doc) {
   doc.employees = doc.employees.map(function(employee) {
       return db.employees.find({ "_id": { "$in": doc.employees } }).toArray();
   })
})

Mongoose works on the concept of using the "schema" definition to "know" which collection to execute the "other query" on and then return the "joined" results to you. 猫鼬的工作原理是使用“模式”定义“知道”哪个集合来执行“其他查询”,然后将“联接”结果返回给您。 But it is not a single query but multiple hits to the database. 但这不是单个查询,而是对数据库的多次命中。

Other schemes might "keep" the referenced collection information in the document itself, as opposed to relying on the "model code" to get that information. 其他方案可能会“保留”文档本身中引用的集合信息,而不是依赖于“模型代码”来获取该信息。 But the same principle applies where you need to make another call to the database and perform some type of "merge" in the API provided. 但是,如果需要再次调用数据库并在提供的API中执行某种类型的“合并”,则适用相同的原则。

So it all falls down to your choice. 因此,一切都取决于您的选择。 Either you "embed" the data and live with that cost, or you "reference" the data and live with the network "cost" that is associated with multiple database hits. 您要么“嵌入”数据并以该成本承受费用,要么“参考”数据并以与多个数据库命中关联的网络“成本”承受费用。

The key point here is "nothing is free", and not even the way that SQL RDBMS perform "joins" which also has a "cost" of it's own and is a lot of the reasoning why NoSQL solutions like MongoDB do it this way and "do not support joins" in a native fashion for the "cost" involved in distributed data systems. 这里的关键点是“没有什么是免费的”,甚至不是SQL RDBMS执行“联接”的方式,这也有其自身的“成本”,这是为什么像MongoDB这样的NoSQL解决方案以这种方式做到这一点的很多原因,以及对于分布式数据系统中涉及的“成本”,以本机方式“不支持联接”。

The main lesson here is to "do what suits you and your application", and not just choose the "coolest thing right now", but basically expect what you get from choosing different storage solutions. 这里的主要课程是“做适合您和您的应用程序的事情”,而不仅仅是选择“现在最酷的事情”,而是基本上期望您从选择不同的存储解决方案中得到什么。 They all have their own purposes. 他们都有自己的目的。 Horses for Courses as the saying goes. 俗话说,马为课程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM