【问题标题】:rmongodb: how to enforce field ordering by specifying in the projection query?rmongodb:如何通过在投影查询中指定来强制执行字段排序?
【发布时间】:2017-06-23 19:53:14
【问题描述】:

我有一些数据正在尝试使用 rmongodb 包从 mongodb 检索到 R 中。在某个时间点,存储文档中字段的顺序发生了变化。

我试图强制我的投影查询通过明确指定尝试的方法来保持投影字段的顺序:SO question,如下所示:

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

我似乎无法找到一个好的答案。它按照它们在数据库中的顺序返回字段,当然,这些字段已更改为列表。

这意味着,我必须编写什么样的循环代码才能将返回的结果组织成类似数据框的结构,这显然会造成严重破坏。

知道如何按指定顺序获取字段而不是 DB 中的内容吗?

【问题讨论】:

  • 我认为 $project 将是您的解决方案。
  • 不完全确定你在问什么;您能否提供示例数据和/或预期结果?为什么你不能在 R 中进行排序,并且你没有使用聚合框架?
  • 在数据库中,在某些时候,每个文档中存储上述字段的顺序发生了变化。 MongoDB 按照它们在数据库中出现的顺序返回这些字段。我希望它们按我指定的顺序返回。当然,我可以在 R 中重新排序,我正在这样做。但是,这需要我遍历整个数据(返回列表)并对列表的每个条目进行排序。
  • 另外,在指定要返回的字段时,只能使用0(不返回)或1(返回)。

标签: r mongodb aggregation-framework rmongodb


【解决方案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

现在有点无耻的自我推销。我一直在研究返回 data.table 对象的 mongolite 扩展。 这里的想法是提高返回对象的速度,但前提是返回的结果集可以使用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()

【讨论】:

  • @Arun - 它还可以进一步改进,我只需要学习/改进我的 C 编程..
  • @Arun - 另外,感谢#1659 - 我现在可以返回_id 字段:)
猜你喜欢
  • 1970-01-01
  • 2012-08-12
  • 2014-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多