使用聚合,匹配和查找,使用MongoDB一次查询多个集合

时间:2018-10-12 12:28:14

标签: mongodb

我在这里遇到了一个问题,因为在尝试通过多个集合进行查询时,我试图将$ lookup的用法包住头,如此处:https://stackoverflow.com/a/43653679和此处:{ {3}}

有3个收藏夹:

用户-可以在其中使用“ 电子邮件”字段

配置-可在其中使用“ vpn ”字段

固件-可在其中使用“ 版本”字段


我的目的是计算符合以下条件的用户数量:

  • 电子邮件 =! @ yahoo.com,@ gmail.com,@ hotmail.com
  • vpn 已启用
  • 版本是123

能否请您帮助我了解查询的外观? 非常感谢!

2 个答案:

答案 0 :(得分:1)

我现在不在我的工作站上,但是我相信这是您想要的。

您在问题中上面提到的链接完美地说明了您要做什么。好像您很难在头脑中解决它。(我们都这样做。我知道很多事)

为将来参考,通常将其视为/标记为您所参考问题的重复,但我发现您是新来的,出于某种原因,我的心情很好。希望这会有所帮助,如果没有让我知道!欢迎来到社区!

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"> }

答案 1 :(得分:1)

我最终使用了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)`)