2013-05-03 102 views
4

我試圖從rmongodb訪問mongodb聚合框架。它應該可以通過mongo.command(),但我不能得到正確的BBS。如何從rmongodb R包訪問MongoDB的聚合框架

這是一個可複製的例子。在R,建立一個測試集合:

mongo <- mongo.create() 
db <- "test" 
ns <- "test.people" 

buf <- mongo.bson.buffer.create() 
mongo.bson.buffer.append(buf, "name", "John") 
mongo.bson.buffer.append(buf, "age", 22L) 
b <- mongo.bson.from.buffer(buf) 
mongo.insert(mongo, ns, b); 

buf <- mongo.bson.buffer.create() 
mongo.bson.buffer.append(buf, "name", "John") 
mongo.bson.buffer.append(buf, "age", 35L) 
b <- mongo.bson.from.buffer(buf) 
mongo.insert(mongo, ns, b); 

buf <- mongo.bson.buffer.create() 
mongo.bson.buffer.append(buf, "name", "Fred") 
mongo.bson.buffer.append(buf, "age", 27L) 
b <- mongo.bson.from.buffer(buf) 
mongo.insert(mongo, ns, b); 

Now, on the mongo console, the following works: 

use test 
db.runCommand({ 
    aggregate : "people", pipeline : [ 
    { $group : 
    { _id : '$name', 
     total : { $sum : 1 } } } ] 
}) 

這似乎是R中下面將達到同樣的效果:

mongo.command(mongo, "test", list(
    aggregate="people", 
    pipeline=list(
     group=list(
     "_id"="$name", 
     total=list("$sum"=1) 
    ) 
    ) 
)) 

這是行不通的。

對於這個特定的聚合,我知道還有其他方法可以做到這一點。我只是把它作爲一個簡單的例子,但我希望在未來能夠找到更復雜的聚合。

此外,我知道另一個m包的mongodb,我可能會考慮做這個技巧,但我現在非常重視使用這個包。

回答

2

首先,下面的代碼將會給你結果你想:

sub.buf <- mongo.bson.buffer.create(); 
    mongo.bson.buffer.start.object(sub.buf, "$group"); 
    mongo.bson.buffer.append(sub.buf, "_id", "$name"); 
    mongo.bson.buffer.start.object(sub.buf, "total"); 
    mongo.bson.buffer.append(sub.buf, "$sum", 1L); 
    mongo.bson.buffer.finish.object(sub.buf); 
    mongo.bson.buffer.finish.object(sub.buf); 
sb <- mongo.bson.from.buffer(sub.buf); 

buf <- mongo.bson.buffer.create(); 
mongo.bson.buffer.append(buf, "aggregate", "people"); 
    mongo.bson.buffer.start.array(buf, "pipeline"); 
    mongo.bson.buffer.append(buf, "0", sb); 
    mongo.bson.buffer.finish.object(buf); 
cmd <- mongo.bson.from.buffer(buf); 

我發現在rmongodb執行聚集的挑戰是用戶:

  1. 幾乎是需要使用bson緩衝區
  2. 需要將管道參數指定爲數組
  3. 必須標註管道陣列整數中的條目 (我相信這需要指定實際的聚合機制作爲一個子BSON對象)

我可能是錯的(3),雖然我還沒有看到關於如何執行「組合」聚合的任何其他示例,這些聚合會折扣語句。

祝你好運!

0

你的代碼看起來像它會產生階段名爲"group"的聚合管道,並且沒有這樣的管線運算符。運營商是"$group",這可能是唯一需要糾正的問題。但是,我懷疑只有一個「元素」使用list()會創建一個子文檔,而不是用一個文檔創建一個數組,這是一個管道應該是什麼的數組。您可以嘗試使用單個元素顯式創建數組,特別是在對象中正確獲取「$ group」的唯一方法。

... 
mongo.bson.buffer.start.array(buf, "pipeline") 
mongo.bson.buffer.append(buf, "$group", ... etc 
mongo.bson.buffer.finish.object(buf)