2014-02-16 47 views
0

我有,我已經導入到MongoDB中按以下格式的主機掃描數據:需要對MongoDB的聚集一些幫助/引導/ MapReduce的查詢

{ 
    "_id" : ObjectId("52fd928c62c9815b36f66e68"), 
    "date" : "1/1/2014", 
    "scanner" : "123.9.74.172", 
    "csp" : "aws", 
    "ip" : "126.34.44.38", 
    "port" : 445, 
    "latt" : 35.685, 
    "long" : 139.7514, 
    "country" : "Japan", 
    "continent" : "AS", 
    "region" : 40, 
    "city" : "Tokyo" 
} 
{ 
    "_id" : ObjectId("52fd928c62c9815b36f66e69"), 
    "date" : "1/1/2014", 
    "scanner" : "119.9.74.172", 
    "csp" : "aws", 
    "ip" : "251.252.216.196", 
    "port" : 135, 
    "latt" : -33.86150000000001, 
    "long" : 151.20549999999997, 
    "country" : "Australia", 
    "continent" : "OC", 
    "region" : 2, 
    "city" : "Sydney" 
} 
{ 
    "_id" : ObjectId("52fd928c62c9815b36f66e6a"), 
    "date" : "1/1/2014", 
    "scanner" : "143.9.74.172", 
    "csp" : "aws", 
    "ip" : "154.248.219.132", 
    "port" : 139, 
    "latt" : 35.685, 
    "long" : 139.7514, 
    "country" : "Japan", 
    "continent" : "AS", 
    "region" : 40, 
    "city" : "Tokyo" 
} 

既然「新來蒙戈,我一直在尋找的聚合框架和MapReduce弄清楚如何創建某些查詢我不能,但是,我的生活弄清楚如何做的事情就這麼簡單。

  1. 數的不同具有「日期」爲「1/1/2014」的「端口」445的「ip」地址

  2. 返回最開放的「端口」中的「IP」地址,通過「日期」

  3. 計數的獨特的「IP」地址,通過「CSP」,爲每一位「約會」在

任何幫助將不勝感激。我一直在閱讀和閱讀,但查詢保持超過16MB的限制。正如你可以看到下面,我有很多的條目:

{ 
    "ns" : "brisket.my_models", 
    "count" : 117715343, 
    "size" : 25590813424, 
    "avgObjSize" : 217.3957342502073, 
    "storageSize" : 29410230112, 
    "numExtents" : 33, 
    "nindexes" : 1, 
    "lastExtentSize" : 2146426864, 
    "paddingFactor" : 1, 
    "systemFlags" : 1, 
    "userFlags" : 0, 
    "totalIndexSize" : 3819900784, 
    "indexSizes" : { 
     "_id_" : 3819900784 
    }, 
    "ok" : 1 
} 
+0

你可以添加你試過的東西嗎?查詢乍一看對於聚合框架來說很簡單,但如果達到16mb的限制,則需要在MongoDB 2.6發佈之前對結果進行更多限制。 – WiredPrairie

回答

0

1)db.my_models.distinct("ip", { "port": "445", "date": "1/1/2014" })
2)

db.my_models.aggregate([ 
    { $group: 
     { 
      _id: { ip: "$ip", date: "$date" }, 
      open_ports: { $addToSet: "$port" } 
     } 
    }, 
    { $unwind: "$open_ports" }, 
    { $group: 
     { 
      _id: "$_id", 
      open_ports_count: { $sum: 1 } 
     } 
    }, 
    { $sort: { "open_ports_count": -1 }, 
    { $limit: 10 } 
]) 

3)db.my_models.distinct("ip", { "csp": <some_value>, "date": <RegExp_for_January> })

在3點,你可以使用正則表達式1月的任何一天。你可以閱讀JavaScript RegExp來創建它。
可能是我不understund你想要什麼點2.「按日期」另一個查詢:

db.my_models.aggregate([ 
    { $match: { "date": <Your_date> } }, 
    { $group: 
     { 
      _id: "$_id", 
      open_ports: { $addToSet: "$port" } 
     } 
    }, 
    { $unwind: "$open_ports" }, 
    { $group: 
     { 
      _id: "$_id", 
      open_ports_count: { $sum: 1 } 
     } 
    }, 
    { $sort: { "open_ports_count": -1 }, 
    { $limit: 10 } 
]) 
0

首先,我想最後說,看數據你提出你的日期將開始因爲它們似乎是字符串而不是日期對象,所以對您來說是一個問題。因此,爲了在進一步的回覆中加入任何前綴,你應該查看(如果可能的話)將導入轉換的日期作爲日期類型或至少使日期變爲詞法。

這是真的,你可以使用你目前的「日期」值$substr操作對於一些你想要達到的結果,但是這不會幫助你很多的,你很可能需要在大數據的初始過濾。

ISO 8601風格的日期是詞彙與個月格式。當然具有所有作爲「01」中的2個數字。但轉換日期會更好。

下一個情況的所有查詢的是,如果你打100MB那麼你的第一個階段在任何你正在做的應該是嘗試和$match,你是專門尋找的文件。如果有必要在測試中,則還要添加一個$limit階段,以便保持設置的大小。

如果$匹配真的不是在一天結束的時候爲你工作,MongoDB的的下一個版本有一些選項可以在aggregate每個階段使用在磁盤上的臨時存儲工作。如果您正在評估/正在開發中,而不是正在開發中,那麼查看當前的開發分支版本(2.5.5)和installing可能是值得的。

所以以下我會記住,日期是日期類型,我們使用的是聚集:

對於你的第一個問題(1)最重要的篩選工作組之間選擇如圖所示日期範圍(或絕對值爲字符串):

db.collection.aggregate([ 

    // Limit if you really have to for a working set 
    //{$limit: 10000 }, 

    // Filter with $match just the date and port needed 
    {$match: 
     date: {$gte: new Date("2014-01-01"), $lt: new Date("2014-01-02")}, 
     port: "445" 
    }, 

    // Group on "ip" 
    {$group: { _id: "$ip", count: {$sum: 1} } }, 

    // Optionally sort the results 
    {$sort: { count: -1 } } 

]) 

對於第二個問題(2)要打入日期範圍這一點,並使用真實的日期,或者是可能再次詞彙字符串將有助於該範圍。

db.collection.aggregate([ 
    // Limit if you really have to for a working set 
    //{$limit: 10000 }, 

    // Filter with $match just the dates needed 
    {$match: 
     date: {$gte: new Date("2014-01-01"), $lt: new Date("2014-01-31")}, 
    }, 

    // Moving things that can be some time of day to a whole date 
    {$project: 
     date: { 
      year: {$year: "$date"}, 
      month: {$month: "$date"}, 
      day: {$dayOfMonth: "$date" } 
     }, 
     ip: 1, 
     port: 1 
    }, 

    /* Optional for "unique" ports if required 
    {$group: { _id: { date: "$date", ip: "$ip" }, ports: {$addToSet: "$port"} }}, 
    {$unwind: "$ports" }, 
    {$project: { date: "$_id.date", ip: "$_id.ip" } } 
    */ 

    // Grouping on "date" and "ip" 
    {$group: { _id: { date: "$date", ip: "$ip" }, count: {$sum: 1} }}, 

    // Sort the results by date and 
    {$sort: { 
     "_id.date.year": -1, "_id.date.month": -1, "_id.date.day": -1, "count": -1 
    }}, 

    // Get the "first" count for each date. With nice dates 
    {$group: { 
     _id: { 
      date: {$concat: [ 
       {$substr: [ "$_id.date.year", 0, 4 ] }, 
       "-", 
       {$substr: [ "$_id.date.month", 0, 2 ] }, 
       "-", 
       {$substr: [ "$_id.date.day", 0, 2 ] } 
      ]}, 
      ip: "$_id.ip" 
     }, 
     count: {$first: "$count" } 
    }}, 

    // Optionally make the documents nicer 
    {$project: { _id: 0, date: "$_id.date", ip: "$_id.ip", count: 1 } } 

]) 

對於第三個問題(3)再次你想,你在去篩選日期和相關文件:

db.collection.aggregate([ 
    // Limit if you really have to for a working set 
    //{$limit: 10000 }, 

    // Filter with $match just the dates needed 
    {$match: 
     date: {$gte: new Date("2014-01-01"), $lt: new Date("2014-01-31")}, 
    }, 

    // Moving things that can be some time of day to a whole date 
    {$project: 
     date: { 
      year: {$year: "$date"}, 
      month: {$month: "$date"}, 
      day: {$dayOfMonth: "$date" } 
     }, 
     ip: 1, 
     csp: 1 
    }, 

    // Get the set of "unique ip" per "date" and "csp" 
    {$group: { 
     _id: { 
      date: {$concat: [ 
       {$substr: [ "$date.year", 0, 4 ] }, 
       "-", 
       {$substr: [ "$date.month", 0, 2 ] }, 
       "-", 
       {$substr: [ "$date.day", 0, 2 ] } 
      ]}, 
      csp: "$csp" 
     }, 
     ips: {$addToSet: "$ip" } 
    }}, 

    // Unwind the *set* for the next stage 
    {$unwind: "$ips" }, 

    // Count on the current *key* 
    {$group: { _id: "$_id", count: {$sum: 1} }}, 

    // Clean up the documents 
    {$project: { _id: 0, date: "$_id.date", csp: "$_id.csp", count: 1 } } 

]) 

希望使用$匹配讓你的工作設置大小在限制之下,如果需要的話可以考慮減少這些日期範圍,將結果合併到另一個集合中,並在這些縮減的結果上再次運行聚合。即使考慮即將發佈的允許使用磁盤的功能,這仍然是超大型設備中性能最高的方法。