MongoDB 中的查询

Posted

技术标签:

【中文标题】MongoDB 中的查询【英文标题】:Queries in MongoDB 【发布时间】:2012-08-17 09:42:31 【问题描述】:

我正在尝试使用rmongodb 从 MongoDB 数据库中获取信息,以便在 R 中进行进一步处理。但是,我很难真正开始。这个有效:

cursor <- mongo.find(mongo, "people", query=list(last.name="Smith", first.name="John"),
                 fields=list(address=1L, age=1L))
while (mongo.cursor.next(cursor))
  print(mongo.cursor.value(cursor))

现在,如果我想查找名字是“John”、“Bob”或“Catherine”的人怎么办?我试过query=list(last.name="Smith", first.name=c(John, Bob, Catherine)) 但这没有成功。将= 替换为% 也不起作用。

另一个问题是数据库内容是嵌套的,这意味着我有子树、子子树等。例如,对于条目first.name="John", last.name="Smith",我可能有像address, age, occupation 这样的子条目,而对于职业,我可能有类别作为子树(例如,从 2005 年到 2012 年,每年我都会有一个条目,如“失业”、“文员”、“企业家”)。那么,如果我想查找所有 40 岁且在 2010 年失业的名字为“John”的人怎么办?查询会是什么样子?

编辑作为对 Stennie 的回复:这是我的数据库结构和我正在尝试执行的查询的示例。想象一所大学的校友被细分为小组(例如“非常优秀的学生”、“优秀的学生”等)。然后,每个组都包含已分配到该组的人员列表及其详细信息。

(0)..
   _id  : (Object ID) class id
   groupname: (string) unique name for this group (e.g. "beststudents")
   members[11]
       (0)..
           persid : (integer) 1
           firstname: (string)
           surname: (string)
           age: (integer)
           occupation: (string)
       (1)..
           persid : (integer) 2
           firstname: (string)
           surname: (string)
           age: (integer)
           occupation: (string)
#      and so on until (10)..
(1)..
   _id  : (Object ID) class id
   groupname: (string) unique name for this group
   members[3]
       (0)..
           persid : (integer) 1
           firstname: (string)
           surname: (string)
           age: (integer)
           occupation: (string)
#      and so on until (2)..
# and many more

现在假设我对名称为“最佳学生”和“好学生”的组感兴趣,并希望将每个组的每个成员的“姓氏”和“职业”作为 R 对象为了做一些情节,统计数据或其他什么。也许我还想改进这个请求,只接收那些年龄小于 40 岁的成员。现在在阅读了 Stennie 的回复后,我尝试了这种方式:

cursor <- mongo.find(mongo, "test.people",
          list(groupname=list('$in'=c("beststudents", "goodstudents")),
               members.age=list('$lt'=40) # I haven't tried this with my DB, so I hope this line is right
               ),
          fields=list(members.surname=1L, members.occupation=1L)
        )
count <- mongo.count(mongo, "test.people",
          list(groupname=list('$in'=c("beststudents", "goodstudents")),
               members.age=list('$lt'=40)
               )
        )
surnames <- vector("character", count)
occupations <- vector("character", count)
i <- 1
while (mongo.cursor.next(cursor)) 
  b <- mongo.cursor.value(cursor)
  surnames[i] <- mongo.bson.value(b, "members.surname")
  occupations[i] <- mongo.bson.value(b, "members.occupation")
  i <- i + 1

df <- as.data.frame(list(surnames=surnames, occupations=occupations))

运行后没有错误消息,但我得到一个空数据框。这段代码有什么问题?

【问题讨论】:

你能发布一个示例文档吗?理想情况下是一个简化的示例,显示您的查询的典型嵌套。 【参考方案1】:

现在,如果我想查找名字是“John”的人怎么办? 还是“鲍勃”或“凯瑟琳”?

您可以为此使用$in operator:

cursor <- mongo.find(mongo, "test.people",
   list(last.name="Smith", 
        first.name=list('$in'=c('John','Bob','Catherine'))
   )
)

值得阅读 MongoDB Advanced Queries 页面以及 Dot Notation (Reaching Into Objects)。

另一个问题是数据库内容是嵌套的,这意味着 我有子树、子子树等。

数据结构听起来可能难以操作;需要一个文档的实际示例来尝试说明查询。

如果我想找到所有名字为“John”的人 40 岁,2010 年失业?查询会是什么样子?

对数据结构做一些假设,下面是一个简单的“and”查询示例:

cursor <- mongo.find(mongo, "test.people",
    list(
        first.name='John',
        fy2012.job='unemployed',
        age = 40
    )
)

【讨论】:

感谢您的回复,很有帮助。我插入了一个更详细的示例,其中包含我在阅读您的回复后尝试过的代码,但这并没有按应有的方式工作。您知道问题出在哪里吗? @AnjaM:抱歉,在这里错过了您的最后一条评论,这也在描述中添加了一个新示例。您是否能够解决该查询的问题?如果没有,最好单独添加一个问题。【参考方案2】:

这并不是一个真正的答案,因为我自己仍在努力解决某些方面的问题,但这可能有助于您入门: Running advanced MongoDB queries in R with rmongodb

此外,请检查 rmongodb 页面附带的示例应用程序。也就是说,可以在 github 包中访问: https://github.com/gerald-lindsly/rmongodb/blob/master/rmongodb/demo/teachers_aid.R

【讨论】:

以上是关于MongoDB 中的查询的主要内容,如果未能解决你的问题,请参考以下文章

mongoDB中的子查询问题

如何将sql查询转换为mongodb查询中的exists

优化 mongodb 中的查询

MongoDb中的“查询”和“命令”有啥区别

MongoDB 中的查询

MongoDB 中的关联查询MongoDB : aggregate/lookup 对比 Mongoose : ref / populate