2017-01-26 56 views
2

我保存日誌像集團通過IP類

{ 
    "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" 
} 

我想對於像

{ 
    "_id":"10.10.10.0", "count":2, 
    "_id":"10.10.20.0", "count":1, 
    "_id":"10.20.10.0", "count":1, 
} 

我如何去了解這個總結IP接入的輸出來查詢MongoDB的訪問?

+0

是'X-轉發-FROM'固定每個「CustomField」? –

+0

X-FORWARDED-FROM是固定的。 –

+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. 串接數組元素轉換成字符串由IP地址
  5. 組他們
  6. 最後串接「0」到_id字段作爲IP地址的最後部分
+0

謝謝。你的解決方案是工作。但結果不是按IP級別分組的。它是 '_id「:」10.10.10.10「,」count「:1, 」_id「:」10.20.10.192「,」count「:1, 」_id「:」10.10.20.159「, 「count」:1, 「_id」:「10.10.10.150」,「count」:1, } –

+0

起初我錯了你的問題,因爲它有點混淆有關的最後一部分IP地址。不過,我已經更新了我的答案,現在它提供了您想要的輸出。 – Karlen

+0

非常感謝。這行得通。 –

0

如果X-FORWARDED-FROM字符串是固定的每CustomField然後可以通過使用$substr解決。

db.CollectionName.aggregate([ 
    {$group:{ 
     _id:"$CustomField", 
     count:{$sum:1} 
     } 
    }, 
    {$project:{ 
     _id: { $substr: [ "$_id", 17, -1] }, 
     count:1 
     } 
    } 
]) 

其中裝置從啓動。這是的長度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} 
     } 
    } 
]) 
+0

謝謝。你的解決方案是工作。但結果不是按IP級別分組的。它是 '_id「:」10.10.10.10「,」count「:1, 」_id「:」10.20.10.192「,」count「:1, 」_id「:」10.10.20.159「, 「count」:1, 「_id」:「10.10.10。150「,」count「:1, } –

+0

你的意思是通過ip類的前三部分?@WatcharaKangkun –

+0

IP類是指ip地址的前三部分就像 10.10.10.10和10.10.10.150是相同的ip類 –