寻找一种方法,基于另一个集合 MongoDB 的集合从另一个集合返回文档



首先,我有两个集合,userssensors。用户看起来像:

{
"_id" : ObjectId("5d471ec414197a868de1b533"),
"email" : "example_email@hotmail.co.uk",
"hashedPassword" : "hash",
"confirmation_code" : "conf",
"confirmed" : true,
"sensors" : [
"asde22re",
]
}

传感器看起来像:

"_id" : ObjectId("5d4c85d7b032b64f1c1a0b14"),
"sensorId" : "asde22re",
"data" : [
{
"data" : "10343",
"time" : "2019-08-08T20:28:07.241Z"
},
{
"data" : "11002",
"time" : "2019-08-08T20:28:26.594Z"
}
]

我有一个端点GET /sensors,它应该返回用户也可以访问的所有传感器的数据,这可以在users.sensors中找到。

我不确定如何实际谷歌我想要什么(可能是我的无知(,但本质上我需要一个查询,给定users.email它返回相应用户也可以访问的所有传感器。

我可以做到这一点的一种方法是:

dbo.collection('users').findOne({ email: 'example_email' })然后使用此响应,获取users.sensors并对集合中的每个传感器进行foreach,但这似乎效率低下。

如何将其合并到一个查询中?

编辑: 如果有帮助,这就是我试图复制的

dbo.collection('users').findOne({ email }, { fields: { sensors: 1, _id: 0 } }, (err, results) => {
if(err){
return res.json({ err });
}
const { sensors } = results;
dbo.collection('sensors').find({ sensorId: { $in: [sensors] } }).toArray((err, results) => {
if(err){
return res.json({ err });
}
return res.json({ results });
});
});

类似于sql中的"joins",在Mongo中你必须使用"lookup"。

要使用查找,您必须使用"聚合"查询,

所以你需要的查询是,

db.collection('users').aggregate({$match:{ email: 'example_email' }},
{$unwind:{path:"$sensors"}},
{$lookup:{from:"sensor", localField: "sensors", foreignField:"sensorId", as:"sensorDetails"}},
(err, userData)=>{
console.log(userData);
})

那么这个查询在做什么,

请参阅"用户"集合中的"$lookup"行--->,它使用"传感器"字段(用户集合的本地字段,如SQL中的主ID(并从与sensorId匹配的"传感器"集合中获取信息(传感器集合中的外部字段(,并将结果存储在"sensorDetails"字段中。

您可以使用"userData[0].sensorDetails"访问sensorDetails。 传感器详细信息将是数组。

查看有关查找的官方文档 另请阅读有关放松的信息

请尝试以下操作:

dbo.collection('users').aggregate([{ $match: { email: 'example_email@hotmail.co.uk' } }, { $unwind: "$sensors" },
{
$lookup:
{
from: "sensors",
localField: "sensors",
foreignField: "sensorId",
as: "sensorDetails"
}
}, {
$group: { _id: '$_id', "userDetails": { "$first": "$$ROOT" }, "sensors": { "$push": "$sensors" }, "sensorDetails": { "$push": { "$arrayElemAt": ["$sensorDetails", 0] } } }
},
{ $addFields: { 'userDetails.sensors': '$sensors', 'userDetails.sensorDetails': '$sensorDetails' } },
{
$replaceRoot: { "newRoot": "$userDetails" }
}])

使用mongoDB v3.4 或更高版本,您只需使用$lookup即可达到预期的结果,这里您不需要在localField上使用$unwind即使是数组,也不再重要:

dbo.collection('users').aggregate([{ $match: { email: 'example_email@hotmail.co.uk' } },
{
$lookup:
{
from: "sensors",
localField: "sensors",
foreignField: "sensorId",
as: "sensorDetails"
}
}])

最新更新