简体   繁体   English

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

[英]Query multiple collections at once with MongoDB using aggregate, match and lookup

I'm having a bit of an issue here, as I'm trying to wrap my head around the usage of $lookup when doing a query through multiple collections, as explained here: https://stackoverflow.com/a/43653679 and here: https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/ 我在这里遇到了一个问题,因为在通过多个集合进行查询时,我试图用$ lookup来解决问题,如此处所述: https : //stackoverflow.com/a/43653679和此处: https//docs.mongodb.com/manual/reference/operator/aggregation/lookup/

Got 3 collections: 有3个收藏:

Users - where can use ' email ' field 用户 -可以在哪里使用“ 电子邮件 ”字段

Config - where can use ' vpn ' field 配置 -在哪里可以使用' vpn '字段

Firmware - where can use ' version ' field 固件 -可以在何处使用“ 版本 ”字段


My intent is to count the number of users that match these conditions: 我的目的是计算符合以下条件的用户数量:

  • email =! 电子邮件 =! @yahoo.com,@gmail.com,@hotmail.com @ yahoo.com,@ gmail.com,@ hotmail.com
  • vpn is ON VPN已开启
  • version is 123 版本是123

Can you please help me understand how my query should look? 您能帮我了解我的查询外观吗? Thanks a lot! 非常感谢!

I'm not at my workstation at the moment, but I believe this is what you're looking for. 我现在不在我的工作站上,但是我相信这是您想要的。

The links you have addressed above in your question explain perfectly what you're looking to do Just seems you're having difficulty working it out in your head (Which we all do.. I know do a lot) 您在问题中上面已解决的链接可以完美地说明您要做什么,似乎您很难解决(我们都做到了。我知道很多事)

For future reference this would normally be considered/flagged as a duplicate of the question you referenced but I see you're new here and I'm in a great mood for some reason. 为了将来参考,通常会将其视为/标记为您所参考问题的副本,但我发现您是新来的,出于某种原因,我的心情很好。 Hope this helps and if not let me know! 希望这会有所帮助,如果没有让我知道! Welcome to the community! 欢迎来到社区!

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

This (in theory) would return a document like this: 从理论上讲,这将返回如下文档:

 { "_id": <the number of Users with specified "email", "vpn", "version"> }

I ended up using a js script. 我最终使用了js脚本。 Here's most of it: 这是大多数:

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)`)

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

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