这个问题与this one密切相关,我将考虑NoSQL上下文中关于模式设计的建议,但我很好奇地理解这一点:
实际问题
假设您有以下文档:
_id : 2 abcd
name : 2 unittest.com
paths : 4
0 : 3
path : 2 home
queries : 4
0 : 3
name : 2 query1
url : 2 www.unittest.com/home?query1
requests: 4
1 : 3
name : 2 query2
url : 2 www.unittest.com/home?query2
requests: 4
基本上,我想知道
-
在涉及"嵌套度"大于1的数组/文档 struct 的更新场景中,如果可以多次使用MongoDB的位置
$
运算符(details),或以不同的方式使用,请执行以下操作:{ <update operator>: { "paths.$.queries.$.requests" : value } }
(doesn't work)与"仅"不同,我们可以将
$
once用于顶级数组,并将其绑定为"更高级别"的数组使用显式索引:{ <update operator>: { "paths.$.queries.0.requests" : value } }
) (works) 如果可能的话,相应的R语法将是什么样子.
下面是一个可复制的例子.我尽量简明扼要.
Code example
数据库连接
require("rmongodb")
db <- "__unittest"
ns <- paste(db, "hosts", sep=".")
# CONNCETION OBJECT
con <- mongo.create(db=db)
# ENSURE EMPTY DB
mongo.remove(mongo=con, ns=ns)
示例文档
q <- list("_id"="abcd")
b <- list("_id"="abcd", name="unittest.com")
mongo.insert(mongo=con, ns=ns, b=b)
q <- list("_id"="abcd")
b <- list("$push"=list(paths=list(path="home")))
mongo.update(mongo=con, ns, criteria=q, objNew=b)
q <- list("_id"="abcd", paths.path="home")
b <- list("$push"=list("paths.$.queries"=list(
name="query1", url="www.unittest.com/home?query1")))
mongo.update(mongo=con, ns, criteria=q, objNew=b)
b <- list("$push"=list("paths.$.queries"=list(
name="query2", url="www.unittest.com/home?query2")))
mongo.update(mongo=con, ns, criteria=q, objNew=b)
使用显式位置索引更新嵌套数组(works)
这是可行的,但它涉及到第二级数组queries
的explicit索引(嵌套在数组paths
的子文档元素中):
q <- list("_id"="abcd", paths.path="home", paths.queries.name="query1")
b <- list("$push"=list("paths.$.queries.0.requests"=list(time="2013-02-13")))
> mongo.bson.from.list(b)
$push : 3
paths.$.queries.0.requests : 3
time : 2 2013-02-13
mongo.update(mongo=con, ns, criteria=q, objNew=b)
res <- mongo.find.one(mongo=con, ns=ns, query=q)
> res
_id : 2 abcd
name : 2 unittest.com
paths : 4
0 : 3
path : 2 home
queries : 4
0 : 3
name : 2 query1
requests : 4
0 : 3
time : 2 2013-02-13
url : 2 www.unittest.com/home?query1
1 : 3
name : 2 query2
url : 2 www.unittest.com/home?query2
Update of nested arrays with positional $
indexes (doesn't work)
现在,为了让服务器找到数组paths
(paths.$.queries
)中所需的子文档元素,我想用位置$
操作符替换显式0
.
对于documentation,这应该是有效的,因为关键是指定一个"正确"的查询 Select 器:
positional$运算符与update()方法一起使用时,用作更新查询 Select 器的第一个匹配项的占位符:
我想我指定了一个查询 Select 器,does可以找到正确的嵌套元素(由于paths.queries.name="query1"
部分):
q <- list("_id"="abcd", paths.path="home", paths.queries.name="query1")
我猜翻译成"普通MongoDB"语法后,查询 Select 器看起来有点像这样
{ _id: abcd, paths.path: home, paths.queries.name: query1 }
对我来说,这似乎是一个有效的查询 Select 器.事实上,它确实与所需的元素/文档匹配:
> !is.null(mongo.find.one(mongo=con, ns=ns, query=q))
[1] TRUE
我的 idea 是,如果它在顶层工作,为什么不在更高的级别工作(只要查询 Select 器指向正确的嵌套组件)?
然而,服务器似乎不喜欢嵌套或多次使用$
:
b <- list("$push"=list("paths.$.queries.$.requests"=list(time="2013-02-14")))
> mongo.bson.from.list(b)
$push : 3
paths.$.queries.$.requests : 3
time : 2 2013-02-14
> mongo.update(mongo=con, ns, criteria=q, objNew=b)
[1] FALSE
我不确定这是因为MongoDB不支持这一点,还是因为我没有正确使用R语法.