问题描述
您需要使用聚合框架,在该框架中,您将运行一个聚合管道,该管道首先venueList
使用
运算符根据ID 过滤集合中的文档。
第二个流水线将平整化venueList
和sum
子文档数组,以使文档中的数据作为非规范化条目进一步在流水线下方进行处理。该
运营商在这里很有用。
展开后,有必要使用进一步的过滤器,以便仅允许您要聚合的文档进入下一个管道。
主管道将是 运算符阶段,该运算符阶段使用累加器运算符聚合过滤后的文档以创建所需的总和 。为了获得理想的结果,您将需要使用诸如 创建独立计数字段的时间运算符,因为这将 根据名称值将文档数量提供给表达式。
综上所述,请考虑运行以下管道:
db.collection.aggregate([
{ "$match": { "venueList.id": { "$in": ["VID1212", "VID4343"] } } },
{ "$unwind": "$venueList" },
{ "$match": { "venueList.id": { "$in": ["VID1212", "VID4343"] } } },
{ "$unwind": "$venueList.sum" },
{
"$group": {
"_id": null,
"linux": {
"$sum": {
"$cond": [
{ "$eq": [ "$venueList.sum.name", "linux" ] },
"$venueList.sum.value", 0
]
}
},
"ubuntu": {
"$sum": {
"$cond": [
{ "$eq": [ "$venueList.sum.name", "ubuntu" ] },
"$venueList.sum.value", 0
]
}
}
}
}
])
要与mGo配合使用,您可以使用http://godoc.org/labix.org/v2/mgo#Collection.Pipe中的指南转换上述管道。
要获得比上述方法执行速度快得多并且还考虑了总和列表的未知值的更灵活,性能更好的替代方法,请按以下方式运行替代管道
db.collection.aggregate([
{ "$match": { "venueList.id": { "$in": ["VID1212", "VID4343"] } } },
{ "$unwind": "$venueList" },
{ "$match": { "venueList.id": { "$in": ["VID1212", "VID4343"] } } },
{ "$unwind": "$venueList.sum" },
{
"$group": {
"_id": "$venueList.sum.name",
"count": { "$sum": "$venueList.sum.value" }
}
},
{
"$group": {
"_id": null,
"counts": {
"$push": {
"name": "$_id",
"count": "$count"
}
}
}
}
])
解决方法
这个问题基于MongoDB,如何通过选择多个条件来检索所选项目。就像Mysql中的IN条件一样
选择*从场所列表WHERE场所ID输入(场所1,场所2)
我已经附加了我使用过的json数据结构。 [参考:MONGODB的JSON STRUCTUE] 。
例如,它具有一个场所列表,然后在场所列表内,它具有多个属性场所ID,用户代理名称的总和以及总计数作为值。用户代理表示用户Os,浏览器和设备信息。在这种情况下,我使用os
distribution。在这种情况下,我是linux,ubuntu是指特定的场所ID。
就是这样
"sum" : [
{
"name" : "linux","value" : 12
},{
"name" : "ubuntu","value" : 4
}
],
最后,我想通过在MongoDB的一个find查询中选择“ eventidid”列表来获取所有linux用户数。
例如,我想通过条件ID为 VID1212 或 VID4343的 条件来选择所有Linux用户数 __
参考:MONGODB的JSON结构
{
"_id" : ObjectId("57f940c4932a00aba387b0b0"),"tenantID" : 1,"date" : "2016-10-09 00:23:56","venueList" : [
{
"id" : “VID1212”,"sum" : [
{
"name" : "linux","value" : 12
},{
"name" : "ubuntu","value" : 4
}
],“ssidList” : [ // this is list of ssid’s in venue
{
"id" : “SSID1212”,"sum" : [
{
"name" : "linux","value" : 8
},{
"name" : "ubuntu","value" : 6
}
],“macList” : [ // this is mac list inside particular ssid ex: this is mac list inside the SSID1212
{
"id" : “12:12:12:12:12:12”,"sum" : [
{
"name" : "linux","value" : 12
},{
"name" : "ubuntu","value" : 1
}
]
}
]
}
]
},{
"id" : “VID4343”,"sum" : [
{
"name" : "linux","value" : 2
}
],"ssidList" : [
{
"id" : “SSID4343”,"value" : 2
}
],"macList" : [
{
"id" : “43:43:43:43:43:34”,"value" : 2
}
]
}
]
}
]
}
]
}
我正在使用golang作为使用mgo.v2包与mongoldb操纵数据的语言
预期输出为:
输出
- Linux:12 + 2 = 14
- ubuntu:4 + 0 = 4
不要在会场列表中考虑内部列表。