2015-06-29 76 views
1

我有以下記錄:MongoDB:在聚合中使用用戶定義函數的任何方式?

{ "_id" : ObjectId("55889370ba09474fd178d8b8"), "url" : "http://stackoverflow.com/questions/ask"} 
{ "_id" : ObjectId("55889370ba09474fd178d8b4"), "url" : "http://stackoverflow.com"} 
{ "_id" : ObjectId("55889370ba09474fd178d8b2"), "url" : "http://espn.com"} 

我想要做的聚合,他們的根來獲得每個站點的數量。基本上我希望前兩個記錄都屬於同一組(它們具有相同的根)。

我創建了一個用戶定義的函數來將url轉換爲其根。我的想法是使用用戶定義的函數來首先投影記錄(更改url字段),然後通過url進行分組。問題是顯然用戶定義的函數不能用於聚合。它們可用於投影中的where子句,但用where子句投影時不能用於聚合。

有什麼辦法可以聚合我需要的嗎?

編輯:

也許使例子更能說明我要補充一點,如果我如想組由根網站,並指望他們,我會得到這樣的:

{ "_id" : "http://stackoverflow.com", "count" : 2} 
{ "_id" : "http://espn.com", "count" : 1} 
+0

你基本上是在尋找使用**'$ regex' **的**'$ project' **過濾器,但是目前聚合框架沒有這個功能,這裏有一個開放的JIRA [*] * SERVER-11947 **](https://jira.mongodb.org /瀏覽/ SERVER-11947)。 – chridam

+0

那麼目前沒有辦法做到這一點?沒有其他的選擇? –

+0

這不適合http://stackoverflow.com/a/16252753/4573999? –

回答

1

嘗試聚合時使用regex。我想可能會跳過用戶定義的函數。

這個question例如使用它。

在您的特定情況下,解決方法描述爲here。不知道這是你想要的。

否則恐怕你必須映射 - 減少它。

+1

這不是在匹配子句中使用的正則表達式嗎?我不想過濾任何記錄。我只是想在投影過程中改變場,以便在分組過程中可以使用同一個鍵。 –

+0

是的,但我想這也許是個有趣的解決方法:http://stackoverflow.com/a/17493547/1566187你能證實嗎?否則,只需使用map-reduce我會說。 – Elyasin

1

這是一個簡單的解決方案。示例數據是:

> db.test.find() 
{ "_id" : ObjectId("559178703535798edab41c36"), "text" : "aaaasfadf" } 
{ "_id" : ObjectId("559178743535798edab41c37"), "text" : "bfasdfasdf" } 
{ "_id" : ObjectId("559178783535798edab41c38"), "text" : "aasdfsdf" } 
{ "_id" : ObjectId("5591787b3535798edab41c39"), "text" : "asdf" } 
{ "_id" : ObjectId("5591787e3535798edab41c3a"), "text" : "csfd" } 

我想基於字符串的第一個字母組項目(你把你的功能,在這裏提取URL的基礎):

db.test.group({ 
    $keyf : function(doc){ 
     return { 
      key : doc.text.substring(0,1) // extract URL base here 
     } 
    }, 
    $reduce : function(curr, result){ 
     result.count++ 
    }, 
    initial : { 
     count: 0 
    } 
}) 

結果是:

[ 
    { 
     "key" : "a", 
     "count" : 3 
    }, 
    { 
     "key" : "b", 
     "count" : 1 
    }, 
    { 
     "key" : "c", 
     "count" : 1 
    } 
]