【问题标题】:rmongodb: using $or in queryrmongodb:在查询中使用 $or
【发布时间】:2012-08-22 05:51:34
【问题描述】:

我正在努力在 R 和 rmongodb 中使用 $or 创建查询。我想效仿的是 cmdline mongo:

db.people.find( { $or : [ {"person.cell": { $exists : true } }, {"person.home": { $exists : true } } ] })

我想提取 person.cell 不为 null 或 person.home 不为 null 的记录。我可以单独查询每个,但是当我在 rmongodb 中使用 $or 创建缓冲区时无法取回数据,使用 rmongodb 的 R 代码如下所示:

l <- list("$exists"="true")
buf <- mongo.bson.buffer.create()
mongo.bson.buffer.start.array(buf, "$or")
mongo.bson.buffer.append.list(buf, "person.cell", l)
mongo.bson.buffer.append.list(buf, "person.home", l)
mongo.bson.buffer.finish.object(buf)  
b <- mongo.bson.from.buffer(buf)
mongo.find(mongo, "work.people", b)

返回没有记录,没有错误,只是一个空集。正如我所提到的,我可以在 person.cell 或 person.home 上进行查找并获得结果,但当我尝试执行 $or(在 rmongodb 中)以便我使用 person.cell 或 person.home 提取记录时却不行.

我也试过这个:

buf <- mongo.bson.buffer.create()
mongo.bson.buffer.start.array(buf, "$or")
mongo.bson.buffer.start.object(buf, "person.cell")
mongo.bson.buffer.append(buf, "$exists", "true")
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.start.object(buf, "person.home")
mongo.bson.buffer.append(buf, "$exists", "true")
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
b <- mongo.bson.from.buffer(buf)
mongo.find(mongo, "work.people", b)

但是我得到了相同的空集结果(当我查看它时,“b”看起来相同)。我被这个卡住了。

【问题讨论】:

    标签: r mongodb rmongodb


    【解决方案1】:

    您创建 mongo bson 数组的方式是错误的。您缺少零件

    mongo.bson.buffer.start.object(buf, "0")
    ...
    mongo.bson.buffer.finish.object(buf)
    mongo.bson.buffer.start.object(buf, "1")
    ...
    mongo.bson.buffer.finish.object(buf)
    

    有关工作示例,请查看有关以下内容的最新评论: https://github.com/mongosoup/rmongodb/issues/17

    我希望这暂时有效。

    所有 .to.list / .from.list / .append.list 命令都有一个错误。我正在研究一个更简单的解决方案!

    【讨论】:

      【解决方案2】:
      bson <- mongo.bson.from.JSON('{ "$or" : [ {"person.cell": { "$exists" : true } }, {"person.home": { "$exists" : true } } ] }')
      mongo.find(mongo, "work.people", bson)
      

      【讨论】:

        【解决方案3】:

        为了避免编写 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(
          '{"_id":-1}',
          '{"_id":-2, "person":{}}',
          '{"_id":-3, "person":{"x":0}}',
          '{"_id":1,  "person":{"cell":0}}',
          '{"_id":2,  "person":{"home":0}}',
          '{"_id":3,  "person":{"cell":0,"home":0}}'
        )
        
        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" : -1 }
        { "_id" : -2, "person" : { } }
        { "_id" : -3, "person" : { "x" : 0 } }
        { "_id" : 1, "person" : { "cell" : 0 } }
        { "_id" : 2, "person" : { "home" : 0 } }
        { "_id" : 3, "person" : { "cell" : 0, "home" : 0 } }
        

        现在让我们用查询来搜索文档:

        # searching for those objects
        # JSON keys currently are expected to be wrapped in double quotes!
        
        json_qry <- 
        '{
          "$or" : [ 
            {"person.cell": { "$exists" : true } }, 
            {"person.home": { "$exists" : true } } 
          ] 
        }'
        
        cur <- mongo.find(M, "dbx.collx", json_to_bson(json_qry))
        
        while(mongo.cursor.next(cur)) {
            print(mongo.cursor.value(cur))
        }
        

        这就是我们最终得到的结果:

        _id : 1      1.000000
        person : 3   
            cell : 1     0.000000
        
        _id : 1      2.000000
        person : 3   
            home : 1     0.000000
        
        _id : 1      3.000000
        person : 3   
            cell : 1     0.000000
            home : 1     0.000000
        

        【讨论】:

          【解决方案4】:

          我发现这个查询在RMongo 中更容易解决:

          mongo <- mongoDbConnect(dbName="work", host="localhost",port='27017')
          result <- dbGetQuery(mongo, "people","
              { '$or': [
                  {'person.cell':{'$exists':true}},
                  {'person.home':{'$exists':true}}
              ]}"
          )
          

          结果将是data.frame

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-12
            • 2012-09-09
            • 1970-01-01
            相关资源
            最近更新 更多