使用聚合、匹配和查找使用MongoDB一次查询多个集合
我在这里遇到了一点问题,因为我试图在通过多个集合进行查询时,了解$lookup的用法,如下所述: 获得3个系列: 用户-哪里可以使用“电子邮件”字段 Config-哪里可以使用“vpn”字段 固件-哪里可以使用“版本”字段使用聚合、匹配和查找使用MongoDB一次查询多个集合,mongodb,Mongodb,我在这里遇到了一点问题,因为我试图在通过多个集合进行查询时,了解$lookup的用法,如下所述: 获得3个系列: 用户-哪里可以使用“电子邮件”字段 Config-哪里可以使用“vpn”字段 固件-哪里可以使用“版本”字段 我的目的是统计符合这些条件的用户数量: 电子邮件=@雅虎网站,@gmail.com,@hotmail.com vpn已打开 版本为123 你能帮我理解我的查询应该是什么样子吗? 非常感谢 我现在不在我的工作站上,但我相信这就是你要找的 你在上面的问题中提到的链接完美地解
我的目的是统计符合这些条件的用户数量:
- 电子邮件=@雅虎网站,@gmail.com,@hotmail.com
- vpn已打开
- 版本为123
非常感谢 我现在不在我的工作站上,但我相信这就是你要找的 你在上面的问题中提到的链接完美地解释了你想要做的事情,只是看起来你在头脑中很难解决它(我们都这么做……我知道你做了很多) 作为将来的参考,这通常会被视为/标记为与你提到的问题的重复,但我看到你是新来的,出于某种原因,我心情很好。希望这有帮助,如果没有让我知道!欢迎来到社区
db.Users.aggregate([
{ $match: { email: "test@somemail.com" } }, #Get the users that match the email constraints
{
$lookup: { #Get the config document associated to the/each user
from: "Config",
localField: "config_id",
foreignField: "_id",
as: "config"
}
},
{
$match: { #limit the configs with VPNs that are "ON"
"config.vpn": "ON"
}
},
{
$lookup: { #Get the Firmware associated to the/each User
from: "Firmware",
localField: "firmware_id",
foreignField: "_id",
as: "firmware"
}
},
{
$match: { #Limit to only firmwares that are version 123
"firmware.version": 123
}
},
$count: { "_id" }
])
这(理论上)将返回如下文档:
{ "_id": <the number of Users with specified "email", "vpn", "version"> }
{u id:}
我最终使用了一个js脚本。以下是大部分内容:
let vpnConfigs = dbRefs.Devices.VpnConfig.find({"vpn": "on"}).toArray()
let firmwareConfigs = dbRefs.Devices.FirmwareConfig.find({"version": "1.2.1"}).toArray()
let tenants = dbRefs.Users.Tenant.find().toArray()
let filteredDevices = vpnConfigs.filter( vpnConfigModel => firmwareConfigs.some(firmwareConfigModel => vpnConfigModel.parent.id
=== firmwareConfigModel.parent.id) )
let totalDevicesNumber = 0
let filteredTenants = tenants.filter(
tenant => {
if(/@psft\.com|@gmail\.com|@yahoo\.com|@maildrop.cc/.test(tenant.ownerEmail)){
return false;
}
return filteredDevices.some(configModel => configModel.tenantId === tenant._id)
let devicesCount = filteredDevices.filter(configModel => configModel.tenantId === tenant._id).length
totalDevicesNumber += devicesCount
return devicesCount > 0
} )
filteredTenants.map(
tenant => print(tenant.ownerEmail) )
print(`Found ${filteredTenants.length} tenant(s)`)
print(`Found ${totalDevicesNumber} device(s)`)
你好,贾巴。谢谢你善意的回答!事实证明,我不能真正使用这种方法,因为我实际上有两个数据库:Devices DB>Config collection>vpn field+Devices DB>Firmware collection>version field和Users DB>User collection>email field。将这些集合绑定在一起的是一个名为tenantId的字段,存在于所有集合中。我不确定你所说的配置id(通常是配置id)是什么意思,因为根据我的例子,我会说,我将配置id改为vpn等等。你是在mongo shell中尝试这样做,还是用js或python之类的语言编写?另外,我只使用了那些自定义的
\u id
,以表明我指的是客户id
字段。这相当于您的租户使用mongo shell。我想我是做错了,对吧?我建议把你的数据库移到一起,然后按集合分开,这样你就可以使用我上面的逻辑了。如果没有,没有办法在一条命令中完成所有这一切如果这回答了你的问题,请将此标记为答案。这有助于其他人更容易找到答案,并帮助自己获得分数。完成。谢谢你,先生!:)