Aza*_*aza 20 populate mongoose mongodb node.js
在stackoverflow上似乎有很多关于这个主题的Q/A,但我似乎无法在任何地方找到确切的答案.
是)我有的:
我有公司和人员模型:
var mongoose = require('mongoose');
var PersonSchema = new mongoose.Schema{
name: String,
lastname: String};
// company has a reference to Person
var CompanySchema = new mongoose.Schema{
name: String,
founder: {type:Schema.ObjectId, ref:Person}};
Run Code Online (Sandbox Code Playgroud)
我需要的:
找到所有姓氏为"Robertson"的人成立的公司
我尝试了什么:
Company.find({'founder.id': 'Robertson'}, function(err, companies){
console.log(companies); // getting an empty array
});
Run Code Online (Sandbox Code Playgroud)
然后我认为Person不是嵌入式的,而是引用的,所以我使用populate来填充创始人Person,然后尝试使用find和'Robertson'lastname
// 1. retrieve all companies
// 2. populate their founders
// 3. find 'Robertson' lastname in populated Companies
Company.find({}).populate('founder')
.find({'founder.lastname': 'Robertson'})
.exec(function(err, companies) {
console.log(companies); // getting an empty array again
});
Run Code Online (Sandbox Code Playgroud)
我仍然可以使用Person的id作为String来查询公司.但这并不是我想要的,因为你可以理解
Company.find({'founder': '525cf76f919dc8010f00000d'}, function(err, companies){
console.log(companies); // this works
});
Run Code Online (Sandbox Code Playgroud)
Joh*_*yHK 37
您不能在单个查询中执行此操作,因为MongoDB不支持连接.相反,你必须将它分成几个步骤:
// Get the _ids of people with the last name of Robertson.
Person.find({lastname: 'Robertson'}, {_id: 1}, function(err, docs) {
// Map the docs into an array of just the _ids
var ids = docs.map(function(doc) { return doc._id; });
// Get the companies whose founders are in that set.
Company.find({founder: {$in: ids}}, function(err, docs) {
// docs contains your answer
});
});
Run Code Online (Sandbox Code Playgroud)
小智 9
我已经很晚了 :p 但我只是在寻找一个类似的答案,我想我会分享我的想法,以防有人出于同样的原因发现这个。
我找不到通过猫鼬查询来实现这一点的方法,但我认为它可以使用MongoDB 聚合管道
要获得您正在寻找的查询,您可以执行以下操作:
const result=await Company.aggregate([
{$lookup: {
from: 'persons',
localField: 'founder',
foreignField: '_id',
as: 'founder'}
},
{$unwind: {path: '$founder'}},
{$match: {'founder.lastname': 'Robertson'}}
]);
Run Code Online (Sandbox Code Playgroud)
$lookup就像.populate(),用实际数据替换引用。它返回一个数组,因为它可用于匹配多个文档。
$unwind 从数组中删除项目,在这种情况下,只会将单个元素数组转换为字段。
$match然后做它听起来像的事情,只返回与查询匹配的文档。如果需要,您还可以进行比严格相等更复杂的匹配。
一般来说,聚合管道的工作方式是在每一步中不断过滤/修改匹配的文档,直到你得到你想要的。
我没有检查过这方面的性能,但我绝对更喜欢让 Mongo 来做这项工作,而不是过滤掉不必要的结果服务器端。
我想唯一的缺点是结果将只是一个对象数组而不是猫鼬模型,因为管道通常会改变文档的形状。因此,您将无法对返回的数据使用模型的方法。
| 归档时间: |
|
| 查看次数: |
19533 次 |
| 最近记录: |