【问题标题】:MongoDB Why this error : can't append to array using string field name: commentsMongoDB 为什么会出现此错误:无法使用字符串字段名称附加到数组:注释
【发布时间】:2014-01-11 15:50:29
【问题描述】:

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

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

我在 cmets 字段中更新了一个新的子文档。没关系。

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

之后的数据库结构:

{
    "_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"}}}  
)

错误信息:

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

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    好吧,如果您考虑一下,这完全有道理。 MongoDb 具有神奇地解决某些事情的优点和缺点。 当您像这样查询数据库以获取特定的常规字段时:

    { field : "value" }
    

    查询 {field:"value"} 完全有意义,如果 value 是数组的一部分,但 Mongo 会为您解决它,所以如果结构是:

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

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

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

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

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

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

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

    “用 _id:1 从主集合记录中给我”(一个文档) "and cmets里面有哪些cmets和id=3" (array * array)

    第一层很容易解决,cmets.id,第二层是不可能的,因为 cmets 返回一个数组,但是再一层是数组数组,Mongo 得到一个数组数组,因此无法推送一个文档放入数组的所有记录中。

    解决方案是缩小 where 子句以获取 cmets 中的唯一文档(可能是第一个),但这不是一个好的解决方案,因为您永远不知道要查找的文档的位置,使用shell 我认为唯一准确的选择是分两步完成。检查这个有效的查询(无论如何都不是解决方案),但“解决”将它固定到第一条记录的多个数组部分:

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

    【讨论】:

      猜你喜欢
      • 2015-02-18
      • 2020-01-17
      • 2015-01-06
      • 2015-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多