使用mongo.bson.from.list()和$或expression从R查询MongoDB

时间:2014-08-08 15:03:09

标签: r mongodb rmongodb

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()或者从&#34;缓冲区&#34;中构建BSON的替代方法。


请注意,以下三个问题涉及$或但不涉及列表中的BSON创建():

1 个答案:

答案 0 :(得分:1)

为了避免必须编写mongo.bson.buffer语句的序列,我编写了一个包(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

  • 键 - 像$或 - 这样的运算符也需要用双引号括起来。
  • "x":3会导致3被视为双重
  • "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)