【发布时间】:2013-01-06 06:10:56
【问题描述】:
我在理解如何更新子文档(相对于整个子文档)的特定字段的方式时遇到了一些问题。
我似乎已经了解如何查询子文档中的某些字段值,但我不知道如何构建仅更改查询字段的 BSON 文档。
我仍然觉得我还没有完全理解“普通 MongoDB 语法”是如何转换为 R 语法的,以及 update operators 是如何工作的。在这方面的任何提示将不胜感激。
预赛
pkg <- "rmongodb"
lib <- file.path(R.home(), "library")
if (!suppressWarnings(require(pkg, lib.loc=lib, character.only=TRUE))) {
install.packages(pkg, lib=lib)
require(pkg, lib.loc=lib, character.only=TRUE)
}
db <- "__test"
ns.0 <- "user"
ns <- paste(db, ns.0, sep=".")
con <- mongo.create(db=db)
确保空 DB
mongo.remove(mongo=con, ns=ns)
插入文档
本节只是确保数据库中的一些示例数据。这只是一个辅助部分,你可以在精神上跳过!继续“查询”部分并查看“实际查询”以了解可能难以从下面的 R 代码中掌握的文档结构。
文档 1 的 BSON
blist <- NULL
buf <- mongo.bson.buffer.create()
mongo.bson.buffer.append(buf, name="host",
value="unittest.com")
mongo.bson.buffer.start.array(buf, "paths")
mongo.bson.buffer.start.object(buf, "1")
mongo.bson.buffer.append(buf, name="path",
value="home")
mongo.bson.buffer.append(buf, name="url",
value="www.unittest.com/home")
mongo.bson.buffer.start.array(buf, "queries")
mongo.bson.buffer.start.object(buf, "1")
mongo.bson.buffer.append(buf, name="query",
value="?somequery")
mongo.bson.buffer.append(buf, name="url",
value="www.unittest.com/home?somequery")
mongo.bson.buffer.finish.object(buf) # finish query:1
mongo.bson.buffer.start.object(buf, "2")
mongo.bson.buffer.append(buf, name="query",
value="?someotherquery")
mongo.bson.buffer.append(buf, name="url",
value="www.unittest.com/home?someotherquery")
mongo.bson.buffer.finish.object(buf) # finish query:2
mongo.bson.buffer.finish.object(buf) # finish queries
mongo.bson.buffer.finish.object(buf) # finish path:1
mongo.bson.buffer.start.object(buf, "2")
mongo.bson.buffer.append(buf, name="path",
value="somepage")
mongo.bson.buffer.append(buf, name="url",
value="www.unittest.com/somepage")
mongo.bson.buffer.start.array(buf, "queries")
mongo.bson.buffer.start.object(buf, "1")
mongo.bson.buffer.append(buf, name="query",
value="?somequery")
mongo.bson.buffer.append(buf, name="url",
value="www.unittest.com/somepage?somequery")
mongo.bson.buffer.finish.object(buf) # finish query:1
mongo.bson.buffer.start.object(buf, "2")
mongo.bson.buffer.append(buf, name="query",
value="?someotherquery")
mongo.bson.buffer.append(buf, name="url",
value="www.unittest.com/somepage?someotherquery")
mongo.bson.buffer.finish.object(buf) # finish query:2
mongo.bson.buffer.finish.object(buf) # finish queries
mongo.bson.buffer.finish.object(buf) # finish path:2
mongo.bson.buffer.finish.object(buf) # finish paths
mongo.bson.buffer.finish.object(buf) # finish buf
b <- mongo.bson.from.buffer(buf)
blist <- c(blist, list(b))
文档 2 的 BSON
编辑 2012-01-23
我删除了这一部分以使问题更容易理解。
实际插入
sapply(blist, function(ii) {
mongo.insert(mongo=con, ns=ns, b=ii)
})
查询
BSON 查询
buf <- mongo.bson.buffer.create()
mongo.bson.buffer.start.object(buf, "paths")
mongo.bson.buffer.start.object(buf, "$elemMatch")
mongo.bson.buffer.start.object(buf, "queries")
mongo.bson.buffer.start.object(buf, "$elemMatch")
mongo.bson.buffer.append(buf, name="query", value="?somequery")
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
query <- mongo.bson.from.buffer(buf)
> query
paths : 3
$elemMatch : 3
queries : 3
$elemMatch : 3
query : 2 ?somequery
实际查询
> mongo.find.one(mongo=con, ns=ns, query=query)
_id : 7 50feff31ba54a032514b6181
host : 2 unittest.com
paths : 4
1 : 3
path : 2 home
url : 2 www.unittest.com/home
queries : 4
1 : 3
query : 2 ?somequery
url : 2 www.unittest.com/home?somequery
2 : 3
query : 2 ?someotherquery
url : 2 www.unittest.com/home?someotherquery
2 : 3
path : 2 somepage
url : 2 www.unittest.com/somepage
queries : 4
1 : 3
query : 2 ?somequery
url : 2 www.unittest.com/somepage?somequery
2 : 3
query : 2 ?someotherquery
url : 2 www.unittest.com/somepage?someotherquery
更新中
BSON 更新
我想在query 子文档中设置query 字段的值。我查看了MongoDB Manual 并尝试了类似的方法(使用$set 和$ 运算符,因为涉及到数组):
buf <- mongo.bson.buffer.create()
mongo.bson.buffer.start.object(buf, "$set")
mongo.bson.buffer.start.object(buf, "paths")
mongo.bson.buffer.start.object(buf, "$")
mongo.bson.buffer.start.object(buf, "queries")
mongo.bson.buffer.start.object(buf, "$")
mongo.bson.buffer.append(
buf,
name="name",
value="abcd"
)
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
mongo.bson.buffer.finish.object(buf)
bnew <- mongo.bson.from.buffer(buf)
> bnew
$set : 3
paths : 3
$ : 3
queries : 3
$ : 3
name : 2 abcd
实际更新
显然,这不是一个好的选择;-)
res <- mongo.update(mongo=con, ns=ns, criteria=query,
objNew=bnew, flags=mongo.update.multi)
> res
[1] FALSE
2:http://docs.mongodb.org/manual/applications/update/#update-operatorszU
【问题讨论】:
-
最好单独询问您的
update问题,因为可以帮助您解决R语法部分的人数要少得多,而且您的问题的长度有点过分。 -
嗯,我明白你的意思,但 R 语法是这个问题的关键。此外,如果不提供实际的 DB 值,则很难提供可重现的示例,而这又需要“使用 R 语法填充”部分。
-
哎呀。我倾向于同意JohnnyHK。使用 Mongo JS 命令行准确地制作原型,然后移植到 R 可能是最简单的。
-
我删除了第二个文档的代码,以便更容易了解发生了什么;-)