这有点深奥,但是我尝试使用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"
}
}
谢谢,
伊恩