MongoDB为什么会出现此错误:无法使用字符串字段名称附加到数组:comments

时间:2014-01-11 15:50:29

标签: mongodb

我有一个如下所示的数据库结构:

{
    "_id" : 1,
    "comments" : [
        {
            "_id" : 2,
            "content" : "xxx"
        }
    ]
}

我在评论中更新了一个新的子文档。没关系。

db.test.update(
               {"_id" : 1, "comments._id" : 2},
               {$push : {"comments.$.comments" : {_id : 3, content:"xxx"}}}
)

之后的DB结构:

{
    "_id" : 1,
    "comments" : [
        {
            "_id" : 2,
                    "comments" : [
                            {
                                    "id" : 3,
                                    "content" : "xxx"
                            }
                    ],
            "content" : "xxx"
        }
    ]
}

但是当我在注释字段中更新_id为3的新子文档时,出现错误:

db.test.update(  
               {"_id" : 1, "comments.comments.id" : 3},   
               {$push : {"comments.comments.$.comments" : {id : 4, content:"xxx"}}}  
)

错误消息:

  

无法使用字符串字段名称附加到数组:comments

1 个答案:

答案 0 :(得分:3)

嗯,如果你考虑一下,这是完全有道理的。 MongoDb具有神奇地解决某些事物的优点和缺点。 当您在数据库中查询特定的常规字段时,如下所示:

{ field : "value" }

查询{field:“value”}完全有意义,如果值是数组的一部分但是Mongo为你解决它,那么结果是:

{ field : ["value", "anothervalue"] }

Mongo遍历所有这些并将“value”匹配到字段中,您不必考虑它。它完美地工作......只有一个层次,因为如果你有多个级别就无法猜出你想做什么

在您的情况下,第一个查询有效,因为在此示例中就是这种情况:

db.test.update(
               {"_id" : 1, "comments._id" : 2},
               {$push : {"comments.$.comments" : {_id : 3, content:"xxx"}}}
)

在第一级匹配_id,在第二级匹配comments._id,结果得到一个数组,但Mongo能够解决它。

但在第二种情况下,想想你需要什么,让我们隔离where子句:

{"_id" : 1, "comments.comments.id" : 3},

“使用_id:1从主要收藏记录中提供给我”(一份文档) “并且注释里面的注释和id = 3”(数组*数组)

第一级很容易解决,comments.id,第二级是不可能的,因为注释返回一个数组,但是另一个级别是一个数组数组,而Mongo得到一个数组数组,因此无法推送一个文档到数组的所有记录。

解决方案是缩小你的where子句以获得评论中的唯一文档(可能是第一个),但这不是一个好的解决方案,因为你永远不知道你正在寻找的文档的位置是什么,使用shell我认为唯一可行的选择是分两步完成。检查这个有效的查询(不管解决方案),但“解决”多个数组部分将其固定到第一条记录:

db.test.update(
    {"_id" : 1, "comments.0.comments._id" : 3},
        {$push : {"comments.0.comments.$.comments" : {id : 4, content:"xxx"}}}   
)