Mongodb 按IP类别分组

Mongodb 按IP类别分组,mongodb,mongodb-query,aggregation-framework,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.15

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

如何执行此操作?

如果我们假设集合名称为
ips
,并且
的“CustomField”
属性始终表示为
“X-FORWARDED-FROM\u IP\u 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
    }
}])  
它执行以下聚合:

  • 从字符串中获取IP地址
  • 将字符串拆分为包含4部分IP地址的数组
  • 从阵列中删除最后一部分
  • 将数组元素连接成字符串
  • 按IP地址将它们分组
  • 最后将“0”作为IP地址的最后一部分连接到
    \u id
    字段

  • 如果每个
    CustomField
    X-FORWARDED-FROM字符串都是固定的,则可以使用进行求解

    其中17表示从开始。这是X-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}
            }
        }
    ])
    

    对于每个
    CustomField
    X-FORWARDED-FROM
    是否已修复?X-FORWARDED-FROM是否已修复。请尝试我的答案谢谢。我试试你的解决办法。我工作,但不是团体IP课程。请看我的评论。谢谢。你的解决办法是工作。但结果并不是按IP类分组的。它是
    {“\u id”:“10.10.10.10”,“count”:1,“\u id”:“10.20.10.192”,“count”:1,“\u id”:“10.10.20.159”,“count”:1,“\u id”:“10.10.10.150”,“count”:1,}
    起初我搞错了你的问题,因为它与IP地址的最后一部分有关,有点混乱。不过我已经更新了我的答案,现在它给出了您想要的输出。谢谢。你的解决办法是工作。但结果并不是按IP类分组的。它是
    {u id:“10.10.10.10”,“count”:1,“{u id:“10.20.10.192”,“count”:1,“{u id:“10.10.20.159”,“count”:1,“{u id:“10.10.10.150”,“count”:1,}
    你所说的ip类前三部分是什么意思@WatcharaKangkunIP类是指ip地址的前三部分,如10.10.10.10和10.10.10.150是相同的ip类
    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}
            }
        }
    ])