使用查找表丰富mongodb聚合

时间:2018-02-03 22:12:52

标签: mongodb aggregation-framework

这有点深奥,但是我尝试使用MongoDB聚合来汇总一些数据,而不是我需要的所有数据都包含在原始源集合中。例如,在源数据中,我有一个contractKey,但在目标中,我需要将合约作为包含密钥,id和名称的Object。我可以从另一个数据库中找到我需要的其他元素,并且可以轻松地构建Javascript对象,包含映射到键的结果数组,比如这个contract对象:

{
    "8c22ed35-0223-11e8-9e8f-d8257c2a48a1:1131" : {
        "contract" : {
            "name" : "2f3725fa-0e4d-4a0d-acc0-59c1cce0f502.demo-Sandbox-anonymous",
            "id" : 1131,
            "key" : "8c22ed35-0223-11e8-9e8f-d8257c2a48a1:1131"
        }
    },
    "d36ac6d6-7473-11e6-8466-ba5d36e9bcc7:1001" : {
        "contract" : {
            "name" : "Default Contract for Policy Manager Services",
            "id" : 1001,
            "key" : "d36ac6d6-7473-11e6-8466-ba5d36e9bcc7:1001"
        }
    }
}

我在努力的方法是如何在聚合函数中访问这些数组。我正在从mongo shell运行聚合,并且有一个脚本,其中包含在开始时生成这些数组的代码。一旦我得到总结,我就试试这个:

db.AUDIT.aggregate([ 
    {
        $match : {
            containerKey: "3cfe0914-3ef3-4135-9795-4b8cb7d8" // Just here to only get data from my ND while testing
        }
    }, 
    {
        $group : {
            _id : { // This will aggregate by 7 different elements starting with the time slice
                timestamp: { $dateToString: // Convert the ISO Date to the internal format we use
                    {
                        format: "%Y-%m-%d %H:%M:%S.%LZ",
                        date: { $subtract : [ "$requestDtsCal", { // The start date of each block
                            $mod : [ { // The remainder
                                $subtract : [ "$requestDtsCal", baseDate ] // The offset
                                }, divisor ] // The interval
                            } ]
                        }
                    }
                }, 
                serviceKey: "$serviceKey",
                operationuuid: "$operationuuid",
                contractKey: "$contractKey",
                bindingTemplateKey: "$bindingTemplateKey",
                containerKey: "$containerKey",
                status: { $or: [ "$isSoapFaultByMP", "$isSoapFaultByNextHop" ]} // Set a status variable in the id based on if there is any fault
            },
            // For each group, we determine which elements we want to pass to the next stage of the lifecycle
            _count: {$sum: 1}, // Could all the documents matched
            // For each of these section this data will be the same for all records as these are all part of the aggregation group
            // use the $first operator to just take the value of the elements from the first document in the group
            contract : contracts["$contractKey"],
            container: {$first: { name: "$containerName", id: "$containerId", key: "$containerKey"}},  // Build the container object
.....

注意contract : contracts["$contractKey"],当我尝试运行时,我收到错误:

assert: command failed: {
    "ok" : 0,
    "errmsg" : "the group aggregate field 'contract' must be defined as an expression inside an object",
    "code" : 15951
} : aggregate failed

所以要么我有一些语法错误,要么我尝试做一些我无法做到的事情。有什么想法吗?

更新

我意识到我需要将其转换为表达式,因此我将其更改为:

contract : {$first: contracts["$contractKey"]},

这不会失败,但是它没有找到表中的对象,所以我最终会在结果中找到未定义的合同对象。

{
    "_id" : ObjectId("5a76463a47f407556afc9192"),
    "_count" : 180.0,
    "contract" : undefined,
    "container" : {
        "key" : "acb7eb7f-b28e-4ead-944f-ed116d61"
    },
    "service" : {
        "name" : "Metadata Exchange Service",
        "id" : 20052,
        "key" : "uddi:soa.com:ws-mex-servicekey"
    },
    "organization" : {
        "name" : null,
        "id" : 1000,
        "key" : "uddi:soa.com:managementconfigurationbusinesskey"
    },
    "operation" : {
        "name" : "GetMetadata",
        "id" : 2628,
        "key" : "e10a535e-7473-11e6-8466-ba5d36e9bcc7"
    },
    "binding" : {
        "id" : 2514,
        "key" : "uddi:d6e13584-7655-11e6-8911-aed52c780d1b"
    },
    "timestamp" : "2018-02-03 22:00:00.000Z",
    "contractKey" : "d36ac6d6-7473-11e6-8466-ba5d36e9bcc7:1001",
    "containerKey" : "acb7eb7f-b28e-4ead-944f-ed116d61",
    "serviceKey" : "uddi:soa.com:ws-mex-servicekey",
    "organizationKey" : "uddi:soa.com:managementconfigurationbusinesskey",
    "bindingKey" : "uddi:d6e13584-7655-11e6-8911-aed52c780d1b",
    "operationKey" : "e10a535e-7473-11e6-8466-ba5d36e9bcc7",
    "response" : {
        "size" : {
            "sum" : 61200
        },
        "time" : {
            "min" : 3,
            "max" : 6,
            "avg" : 4.33333333333333,
            "sum" : 780
        }
    },
    "request" : {
        "qosviolation" : {
            "sum" : 0
        },
        "size" : {
            "min" : 335,
            "max" : 346,
            "sum" : 61200
        },
        "count" : {
            "sum" : 180.0
        },
        "status" : "Success"
    }
}

谢谢,

伊恩

0 个答案:

没有答案