【发布时间】:2015-09-15 02:55:17
【问题描述】:
我有如下结构的文档,其中每个数组元素包含“n”和“v”作为不同类型数据的键和值。我需要按“ipaddress”的“n”值对它进行分组,并计算集合中不同的总组合。但是,值相似但不相同。 (例如:ip、ip_addr 和 ipaddr)
> db.final.find().pretty()
{
"_id" : 2,
"props" : [
{
"n" : "loc",
"v" : "NW"
},
{
"n" : "logtype",
"v" : "1"
},
{
"n" : "ip",
"v" : "1.1.1.1"
},
{
"n" : "pro",
"v" : "tcp"
},
{
"n" : "port",
"v" : "13438"
}
]
}
{
"_id" : 5,
"props" : [
{
"n" : "loc",
"v" : "NW"
},
{
"n" : "logtype",
"v" : "1"
},
{
"n" : "ip",
"v" : "1.1.1.1"
},
{
"n" : "pro",
"v" : "tcp"
},
{
"n" : "port",
"v" : "53"
}
]
}
{
"_id" : 1,
"props" : [
{
"n" : "loc",
"v" : "NW"
},
{
"n" : "logtype",
"v" : "2"
},
{
"n" : "ip_addr",
"v" : "2.2.2.2"
},
{
"n" : "pro",
"v" : "udp"
},
{
"n" : "port",
"v" : "53"
}
]
}
{
"_id" : 3,
"props" : [
{
"n" : "loc",
"v" : "NW"
},
{
"n" : "logtype",
"v" : "3"
},
{
"n" : "ipaddr",
"v" : "1.1.1.1"
},
{
"n" : "pro",
"v" : "tcp"
},
{
"n" : "port",
"v" : "53"
}
]
}
{
"_id" : 4,
"props" : [
{
"n" : "loc",
"v" : "LA"
},
{
"n" : "logtype",
"v" : "3"
},
{
"n" : "ipaddr",
"v" : "1.1.1.1"
},
{
"n" : "pro",
"v" : "udp"
},
{
"n" : "port",
"v" : "53"
}
]
}
{
"_id" : 6,
"props" : [
{
"n" : "loc",
"v" : "LA"
},
{
"n" : "logtype",
"v" : "1"
},
{
"n" : "ip",
"v" : "1.1.1.1"
},
{
"n" : "pro",
"v" : "udp"
},
{
"n" : "port",
"v" : "53"
}
]
}
查询选择条件如下:
- 如果“loc”为“NW”且“logtype”为“1”,则“ipaddress”=“ip”
- 如果“loc”为“NW”且“logtype”为“2”,则“ipaddress”=“ip_addr”
- 如果“loc”为“NW”且“logtype”为“3”,则“ipaddress”=“ipaddr”
- 端口是“53”
- pro 是“udp”或“tcp”
- 按“ipaddress”分组
我想要这样的结果。
{"ipaddress" : "2.2.2.2" , count : 1}
{"ipaddress" : "1.1.1.1" , count : 2}
这是我目前所拥有的:
db.final.aggregate([
{ "$match": {
"$and": [
{"props" : {"$elemMatch": { "n": "port", "v": "53" }}},
{"props" : {"$elemMatch": { "n": "pro", "v": {"$in" : [/udp/, /tcp/]} }}}
]
}},
{ "$unwind": "$props" },
{
"$project": {
"_ipaddress": {
"$cond": {
"if": { "$eq": [ "$props.n", "ip" ] },
"then": "$props.v",
"else": {
"$cond": {
"if": { "$eq": [ "$props.n", "ip_addr" ] },
"then": "$props.v",
"else": {
"$cond" : {
"if": { "$eq": [ "$props.n", "ipaddr" ] },
"then": "$props.v",
"else" : 0
}
}
}
}
}
},
"_id": 1,
"props" : 1
}
},
{ "$group": {
"_id": "$_id",
"_ipaddress": {
"$min": {
"$cond": [ { "$ne": [ "$_ipaddress", 0 ] }, "$_ipaddress", false ]
}
},
"pro": {
"$min": {
"$cond": [ { "$eq": [ "$props.n", "pro" ] }, "$props.v", false ]
}
},
"logtype": {
"$min": {
"$cond": [ { "$eq": [ "$props.n", "logtype" ] }, "$props.v", false ]
}
},
"port": {
"$min": {
"$cond": [ { "$eq": [ "$props.n", "port" ] }, "$props.v", false ]
}
}
} },
{ "$group": {
"_id": {
"_ipaddress": "$_ipaddress",
},
"count": { "$sum": 1 }
}}
])
但我不知道如何结合“loc”和“logtype”条件。
【问题讨论】:
标签: mongodb mongodb-query aggregation-framework