2017-05-26 59 views
0

我有一個MongoDB集合division_entry。按名稱分組時分成時間段

我希望按標籤過濾,然後按時間和不同的唯一值進行過濾。 最後,我想要在給定的時間跨度內獨特的所有不同的值。

目前,我必須在代碼中存儲每個時間間隔的通話時間。這導致呼叫過多。 當前 -

db.division_entry.aggregate([{$匹配:{$和:[{ 「division.label」: 「ABCD」},{ 「時間戳」:{$ GT:1495448249635,$ LT:1495448249641}} ]}},{$組:{_id: 「$獨特的」}},{$數: 「值」}])

幫助實際結果是非常讚賞。

編輯: 更多細節:

{ 
      "_id" : "1", 
      "timestamp" : NumberLong("1495448249640"), 
      "unique" : "One", 
      "division" : [ 
        { 
          "label" : "ABCD" 
        } 
      ] 
    } 
    { 
      "_id" : "3", 
      "timestamp" : NumberLong("1495448249636"), 
      "unique" : "Two", 
      "division" : [ 
        { 
          "label" : "ABCD" 
        } 
      ] 
    } 
    { 
      "_id" : "2", 
      "timestamp" : NumberLong("1495448249650"), 
      "unique" : "Two", 
      "division" : [ 
        { 
          "label" : "ABCD" 
        } 
      ] 
    } 

db.division_entry.aggregate([{ $match : { $and : [ { "division.label": "ABCD"}, { "timestamp" : { $gt: 1495448249635, $lt: 1495448249651 }} ] } } , {$group : { _id : "$unique"} }]) 
     { "_id" : "Two" } 
     { "_id" : "One" } 

db.division_entry.aggregate([{ $match : { $and : [ { "division.label" : "ABCD"}, { "timestamp" : { $gt: 1495448249635, $lt: 1495448249651 } } ] } } , {$group : { _id : "$unique"} } , {$count : "value" }]) 
     { "value" : 2 } 

這是在特定的時間範圍,這在匹配查詢指定完成。假設我希望獲得一天數據的分鐘精度,我將不得不撥打1440個這樣的電話,在每次電話會議中,時間戳範圍將覆蓋一分鐘。

我希望能夠幫助挖掘並同時爲「獨特」字段找到不同的值。

+0

這裏的實際分組是什麼?您是否應該看到不同的「時間戳」,或者它是否只是「時間戳」中的「唯一」值?從你的問題和這麼小的樣本中分辨出來有點難。有幾種技術可以解決這個問題,這對您所包含的聚合流水線示例無效無濟於事。如果您可以編輯以澄清這些問題,並且最好具有預期輸出,那麼這將有助於您的問題。 –

+0

如果您可以指定您的「桶」非常簡單,如「常規間隔」(即1分鐘,1小時等),那麼這也會使事情變得更加清晰。包含的查詢時間戳僅相隔6毫秒,這可能並不能真正表明您正在嘗試執行的操作。 –

+0

好多了。所以間隔總是一致的?我的意思是,例如在分組中的所有文件之間1分鐘?當然可以選擇更改該時間間隔,但需要在分組結果之間保持一致的間隔。 –

回答

1

對於固定時間間隔做的是執行一些「日期數學」到文檔中的當前"timestamp"值圓了爲分組共同的區間值的最好的事情。做到這一點的最佳方法是使用標準匹配減去應用於所需時間間隔的毫秒值的模數(餘數)。

在聚合框架,我們提供使用$subtract$mod與當前文檔一起形成複合鍵的黨"unique"字段值_id關鍵$group

db.division_entry.aggregate([ 
    // Sanely restrict to a range of dates to analyse - here is one day 
    { "$match": { 
    "timestamp": { "$gte": 1495670400000, "$lt": 1495756800000 } 
    }}, 

    // Group by interval - example of 1 hour (1000ms * 60sec * 60min) 
    { "$group": { 
    "_id": { 
     "time": { 
     "$subtract": [ 
      "$timestamp", 
      { "$mod": [ "$timestamp", (1000 * 60 * 60) ] } 
     ] 
     }, 
     "unique": "$unique" 
    }, 
    "count": { "$sum": 1 } 
    }} 
]) 

因此,對於不同的時間間隔,你需要的是提供數學爲所需的間隔:

  • 一分鐘(1000 * 60)
  • 1小時(1000 * 60 * 60)
  • 1天(1000 * 60 * 60 * 24)

僅供參考,有一個新引進的$bucket運營商,但它的目的是相當對於「分割點」即不是統一。即0-5分鐘,6-20分鐘,20-50分鐘和超過50分鐘作爲示例用例。

對於任何「統一」,基於數學的方法是最有效實施的。

+0

你會怎麼去執行$減法Java?官方文檔提到了自己構建文檔,我正在尋找更基於代碼/更快的解決方案。 – MonsieurBeilto

+0

@MonsieurBeilto它取決於實現。你可以隨時[問一個新問題](https://stackoverflow.com/questions/ask)或者只是搜索現有的答案,可能已經在這裏(我可能已經寫了一些)。所有BSON基本上都是一個'Document'或一個標準的Java'List'。 –

0

這是根據Neil的回答得到的啓發。

我另外想要的是不同的時間間隔和獨特的uuids數量。他提供的答案爲每個唯一的uuid提供了它在q中出現的時間間隔內的次數。

db.divisive_entry.aggregate([ 
    { "$match": { 
    "timestamp": { "$gte": 1395448852351, "$lt": 1497428775000 } 
    }}, 

    { "$group": { 
    "_id": { 
     "time": { 
     "$subtract": [ 
      "$timestamp", 
      { "$mod": [ "$timestamp", (1000 * 60 * 60) ] } 
     ] 
     }, 
     "unique": "$unique" 
    }, 
    }}, 

    { "$group": 
    { 
     "_id": "$_id.time", 
     "count" : { "$sum": 1 } 
    } 
    } 
]) 
+0

您可以簡單地留下一條評論來澄清這種差異,並且您的問題中沒有任何內容表明情況正是如此。這也不是一個「線索討論」,而是一個問題和一個明確的答案。如果它是你想要的每個時間段的「獨特的獨特數量」,那麼第二個分組確實是這樣做的方式。下一次你提出一個問題時,你應該評論一下,以便向回答者澄清,而不是讓他們掛在那裏。 –

+0

我做了修改,反映了你的觀點 – MonsieurBeilto