2016-06-18 76 views
0

我有一些數據,我試圖使用rmongodb包從mongodb中檢索到R中。在某個時間點,存儲文檔中的字段順序發生了變化。rmongodb:如何通過在投影查詢中指定強制字段順序?

我試圖迫使我的投影查詢保留通過明確的方式投射固定字段的順序嘗試的:SO question如下:

data <- mongo.find.all(mongo_conn, table, 
          fields = list('id1' = 1, 'id2' = 2, 
             'time' = 3, 'latitude' = 4, 
             'longitude' = 5, '_id' = 0)) 

我似乎無法找到一個很好的答案這個。它按照它們在數據庫中的順序返回這些字段,並將其作爲列表進行更改。

這意味着,它會對我必須編寫哪些類型的代碼以便將返回的結果組織到結構等數據框中產生明顯的混亂。

任何想法如何以指定的順序獲取字段,而不是數據庫中的內容?

+0

[$ project](https://docs.mongodb.com/manual/reference/operator/aggregation/project/)將是您的解決方案,我認爲。 – Shrabanee

+0

不完全確定你在問什麼;你能提供示例數據和/或預期結果嗎?你爲什麼不能在R中進行排序並且你沒有使用聚合框架? – SymbolixAU

+0

在數據庫中,在某些時候,在每個文檔中存儲上述字段的順序已更改。 MongoDB按照它們在數據庫中出現的順序返回這些字段。我希望他們按照我指定的順序返回。當然,我可以重新訂購R,我正在做。但是,這要求我運行整個數據(返回列表)並對列表中的每個條目進行排序。 – Gopala

回答

1

在您鏈接到它的回答說

簡單的答案是,你不能做到這一點。

另見related mongodb ticket

但是,要在data.frame狀結構中的效果,請使用mongolite,它更容易與

工作使用mtcars數據

考慮這個例子
data("mtcars") 

library(mongolite) 

mongo <- mongo(db = "test", 
       collection = "mtcars", 
       url = "mongodb://localhost") 

## insert into database 
mongo$insert(mtcars) 
# Complete! Processed total of 32 rows. 
# [1] TRUE 

mongolite::find會自動簡化查詢結果成data.frame結構

df_results <- mongo$find() 
# Imported 32 records. Simplifying into dataframe... 

head(df_results) 
#      mpg cyl disp hp drat wt qsec vs am gear carb 
# Mazda RX4   21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 
# Mazda RX4 Wag  21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 
# Datsun 710  22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 
# Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 
# Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 
# Valiant   18.1 6 225 105 2.76 3.460 20.22 1 0 3 1 

或者,使用聚合框架

mongo$aggregate(pipeline = '[{ "$project" : { "mpg" : 1, "wt" : 1, "_id" : 0} }, 
          { "$limit" : 5 }]') 

# Imported 5 records. Simplifying into dataframe... 
#  mpg wt 
# 1 21.0 2.620 
# 2 21.0 2.875 
# 3 22.8 2.320 
# 4 21.4 3.215 
# 5 18.7 3.440 

而且現在有點無恥的自我推銷。我一直在研究對mongolite的擴展,它返回一個data.table對象。 這裏的想法是提高返回對象的速度,但前提是返回的結果集可以使用rbindlist來強制轉換。

包裝爲mongolitedt,仍在開發中。

# devtools::install_github("SymbolixAU/mongolitedt") 
library(mongolitedt) 

bind_mongolitedt(mongo) 

mongo$aggregatedt(pipeline = '[{ "$project" : { "mpg" : 1, "wt" : 1, "_id" : 0} }, 
          { "$limit" : 5 }]') 

## now have a data.table object returned 
# Imported 5 records. 
#  mpg wt 
# 1: 21.0 2.620 
# 2: 21.0 2.875 
# 3: 22.8 2.320 
# 4: 21.4 3.215 
# 5: 18.7 3.440 

## clean up 
rm(mongo); gc() 
+0

'mongolitedt'似乎很有趣..展望.. – Arun

+0

@阿倫 - 它可以進一步改善,我只需要學習/提高我的C編程.. – SymbolixAU

+0

@阿倫 - 也,謝謝你[#1659](https:/ /github.com/Rdatatable/data.table/issues/1659) - 我現在可以返回'_id'字段:) – SymbolixAU