按IP类分组

时间:2017-01-26 07:35:17

标签: mongodb mongodb-query aggregation-framework

我在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,
}

我该怎么做?

2 个答案:

答案 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
    }
}])  

它执行以下聚合:

  1. 从字符串中获取IP地址
  2. 将字符串拆分为4部分IP地址的数组
  3. 从数组中删除最后一部分
  4. 将数组元素连接成字符串
  5. 按IP地址分组
  6. 最后连接" 0"到_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}
        }
    }
])