我在MongoDB中保存日志访问,如
{
"Host": "www.foo.com"
"CustomField":"X-FORWARDED-FROM 10.10.10.10"
},{
"Host": "www.foo.com"
"CustomField":"X-FORWARDED-FROM 10.20.10.192"
},{
"Host": "www.foo.com"
"CustomField":"X-FORWARDED-FROM 10.10.20.159"
},{
"Host": "www.foo.com"
"CustomField":"X-FORWARDED-FROM 10.10.10.150"
}
我想使用输出查询摘要ip访问,如
{
"_id":"10.10.10.0", "count":2,
"_id":"10.10.20.0", "count":1,
"_id":"10.20.10.0", "count":1,
}
我该怎么做?
答案 0 :(得分:1)
如果我们假设集合名称为ips
且"CustomField"
属性始终表示为"X-FORWARDED-FROM THE_IP_ADDRESS"
,则以下查询聚合会提供所需的结果:
db.ips.aggregate([{
$project:{
_id:{
$substr:["$CustomField", 17, -1]
}
},
},{
$project: {
ip: {$split:["$_id", "."]}
},
},{
$project: {
ip: {$slice:["$ip", 3]}
},
}, {
$project: {
ip: {
$reduce: {
input: "$ip",
initialValue: "",
in: { $concat : ["$$value", "$$this", "."] }
}
}
}
}, {
$group:{
_id: "$ip", count:{$sum:1}
}
}, {
$project: {
_id:{$concat:["$_id", "0"]},
count: 1
}
}])
它执行以下聚合:
_id
字段作为IP地址的最后一部分答案 1 :(得分:0)
如果每个CustomField
修复了 X-FORWARDED-FROM 字符串,则可以使用$substr解决。
db.CollectionName.aggregate([
{$group:{
_id:"$CustomField",
count:{$sum:1}
}
},
{$project:{
_id: { $substr: [ "$_id", 17, -1] },
count:1
}
}
])
其中 17 表示从...开始。这是 X-FORWARDED-FROM 字符串
的长度<强>更新强>
db.CollectionName.aggregate([
{$project:{
ip: {$concat: [{ $substr: [ "$CustomField", 17,8] },'.0']}
}
},
{$group:{
_id:"$ip",
count:{$sum:1}
}
}
])
MongoDB 3.4 的可以使用
db.CollectionName..aggregate([
{$project:{
ip:{ $split: [ { $substr: [ "$CustomField", 17,-1] }, "." ] }//ip: ["10","10","10","192"]
}
},
{$project:{
ip:{ $concat: [
{ $arrayElemAt: [ "$ip", 0 ] },
" . ",
{ $arrayElemAt: [ "$ip", 1 ] },
".",
{ $arrayElemAt: [ "$ip", 2 ] },
".0"
] }
},
},
{$group:{
_id:"$ip",
count:{$sum:1}
}
}
])