这个问题与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. 在涉及"嵌套度"大于1的数组/文档 struct 的更新场景中,如果可以多次使用MongoDB的位置$运算符(details),或以不同的方式使用,请执行以下操作:

    { <update operator>: { "paths.$.queries.$.requests" : value } } (doesn't work)

    与"仅"不同,我们可以将$ once用于顶级数组,并将其绑定为"更高级别"的数组使用显式索引:

    { <update operator>: { "paths.$.queries.0.requests" : value } }) (works)

  2. 如果可能的话,相应的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)

这是可行的,但它涉及到第二级数组queriesexplicit索引(嵌套在数组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语法.

推荐答案

"位置"操作符仅支持一层深度,并且仅支持第一个匹配元素.

这里有一个JIRA可以追踪你想要的行为:https://jira.mongodb.org/browse/SERVER-831

我不确定它是否会允许不止一场比赛,但我相信它会,因为它将需要如何工作的动态.

Mongodb相关问答推荐

mongo如何通过聚合加载嵌套文档

lexik_jwt_authentication下无法识别的选项api_platform

从 node.js 的 mongodb 集合中删除文档

如何使用 Spring Data MongoDB 通过 GridFS ObjectId 获取二进制流

如何使用 mongoexport 导出排序数据?

Express 无法 PUT/DELETE 方法.出了什么问题?

在 Mongo 中存储嵌套类别的最有效方法?

如何在 mongo JavaScript shell 中中止查询

如何按季度分组日期?

Spring Mongo 条件查询两次相同的字段

MongoDB - 文件大小巨大且不断增长

从每个组中 Select 前 N 行

Mongodb KeyFile 太开放权限

如何使用 mgo 和 Go 查询 MongoDB 的日期范围?

MongoError: The dollar ($) prefixed field '$push' in '$push' is not valid for storage

获取 mongodb 中所有唯一标签的列表

MongoDB 中的多个 $inc 更新

在 MongoDB 中快速搜索数十亿个小文档的策略

Mongodb 按字段名称查找任何值

Mongoid 不在查询中