使用 mongo.bson.from.list() 和 $or 表达式从 R 查询 MongoDB
Posted
技术标签:
【中文标题】使用 mongo.bson.from.list() 和 $or 表达式从 R 查询 MongoDB【英文标题】:Query MongoDB from R with mongo.bson.from.list() and $or expression 【发布时间】:2014-08-08 15:03:09 【问题描述】:test.xxx的内容:
> use test
switched to db test
> db.xxx.find()
"_id" : ObjectId("53e4e4983f6dc95697944b74"), "a" : 1
"_id" : ObjectId("53e4e49a3f6dc95697944b75"), "a" : 2
"_id" : ObjectId("53e4e49c3f6dc95697944b76"), "a" : 3
R 会话:
> library(rmongodb)
> M <- mongo.create("localhost")
> mongo.is.connected(M)
[1] TRUE
>
> qry1 <- list(
+ "a" = 1
+ )
>
> qry2 <- list(
+ "$or" = list(
+ list("a" = 1),
+ list("a" = 3)
+ )
+ )
>
> qry1 <- mongo.bson.from.list(qry1)
> qry2 <- mongo.bson.from.list(qry2)
>
> mongo.count(M, "test.xxx", qry1)
[1] 1
> mongo.count(M, "test.xxx", qry2)
[1] -1
> mongo.get.last.err(M, "test")
connectionId : 16 24
err : 2 $or needs an array
code : 16 2
n : 16 0
ok : 1 1.000000
qry2
的结果应该是 2。
我必须如何改写qry2
的列表?
我特别想使用 mongo.bson.from.list() 而不是 mongo.bson.from.json() 或从“缓冲区”构建 BSON 的替代方法。
请注意,以下三个问题涉及 $or 但不涉及从 list() 创建 BSON:
Using $or array in query How to construct rmongodb query using $and operator rmongodb: using $or in query【问题讨论】:
这是 rmongodb 中的一个错误。不幸的是,目前没有可用的解决方案。请检查此替代方案:***.com/questions/12067020/rmongodb-using-or-in-query 我成功地实现了使用缓冲区的替代方法——这有点乏味。我希望这个错误可能会因为它的高龄而得到修复。我正在使用你的(除了这个非常棒的错误)包作为原型。 R 需要一个与 MongoDB 的良好接口 - rmongodb 是目前最好的选择。所以我——以及世界上成千上万的其他 R 开发者——希望它能够得到积极的维护。肯定会花时间调查这个错误 - 只是我在 C 编程方面没有值得提及的经验。 现在这行得通了!从 github 尝试最新版本的 rmongodb。感谢来自Jeroen Ooms的pull 【参考方案1】:为了避免编写 mongo.bson.buffer-statements 的序列,我编写了一个包 (rmongodbHelper),它将 JSON 或 list() 转换为 BSON 对象,然后可以与 rmongodb 一起使用。
首先让我们设置环境:
library(rmongodb)
# install rmongodbHelper package from GitHub
library(devtools)
devtools::install_github("joyofdata/rmongodbHelper")
library(rmongodbHelper)
# the MongoDB instance
ns <- "dbx.collx"
M <- mongo.create()
mongo.is.connected(M)
mongo.remove(M, ns, json_to_bson(""))
# inserting a number of dummy objects
# JSON keys currently are expected to be wrapped in double quotes!
objs <- c(
'"a":"__int(1)"',
'"a":"__int(2)"',
'"a":"__int(3)"'
)
for(obj in objs)
mongo.insert(M, ns, json_to_bson(obj))
让我们通过 MongoDB shell 看看它们是否插入成功:
> use dbx
switched to db dbx
> db.collx.find().pretty()
"_id" : ObjectId("53fa14315aed8483db4ae794"), "a" : 1
"_id" : ObjectId("53fa14315aed8483db4ae795"), "a" : 2
"_id" : ObjectId("53fa14315aed8483db4ae796"), "a" : 3
现在让我们搜索一个等于 1:
# searching for those objects
# JSON keys currently are expected to be wrapped in double quotes!
json_qry <- '"a":1'
cur <- mongo.find(M, "dbx.collx", json_to_bson(json_qry))
while(mongo.cursor.next(cur))
print(mongo.cursor.value(cur))
这就是我们得到的:
_id : 7 53fa14315aed8483db4ae794
a : 16 1
最后让我们搜索一个等于 1 或 3:
json_qry <-
'
"$or": [
"a":1,
"a":3
]
'
cur <- mongo.find(M, "dbx.collx", json_to_bson(json_qry))
while(mongo.cursor.next(cur))
print(mongo.cursor.value(cur))
及其结果:
_id : 7 53fa14315aed8483db4ae794
a : 16 1
_id : 7 53fa14315aed8483db4ae796
a : 16 3
键 - 也像 $or 这样的运算符 - 需要放在双引号中。
"x":3
将导致 3 被转换为 double
"x":"__int(3)"
将导致 3 被转换为整数
这是使用缓冲区的解决方法:
M <- mongo.create("localhost")
mongo.is.connected(M)
buf <- mongo.bson.buffer.create()
# "$or":[ ...
mongo.bson.buffer.start.array(buf, "$or")
# dummy name "0" for object in array
# "0": ...
mongo.bson.buffer.start.object(buf, "0")
# "a":1
mongo.bson.buffer.append.int(buf, "a", 1)
# ...
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.start.object(buf, "1")
mongo.bson.buffer.append.int(buf, "a", 3)
mongo.bson.buffer.finish.object(buf)
# ...]
mongo.bson.buffer.finish.object(buf)
q <- mongo.bson.from.buffer(buf)
mongo.count(M, "test.xxx", q)
【讨论】:
以上是关于使用 mongo.bson.from.list() 和 $or 表达式从 R 查询 MongoDB的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)