如果数组存在则将对象推入数组,否则在MongoDB中使用对象创建数组

iam*_*dri 12 mongodb mongodb-query

我收集了这样的文件:

{
    _id : "abcd",
    name : "Tom",
    myArray : [
        {
            field1 : "",
            field2 : ""
        }
    ]
},
{
    _id : "efgh",
    name : "Jerry"
}
Run Code Online (Sandbox Code Playgroud)

我有一个新的对象myArray.我想编写一个查询来只更新一个文档.

如果查询与文档匹配_id : "abcd",则将新对象推入myArray字段:

{
    _id : "abcd",
    name : "Tom",
    myArray : [
        {
            field1 : "",
            field2 : ""
        },
        {
            // new object
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

如果查询匹配,则在其中_id : "efgh"创建myArray包含新对象的字段:

{
    _id : "efgh",
    name : "Jerry"
    myArray : [
         {
              // new object
         }
    ]
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

Bla*_*ven 20

要在此解释所有可能的情况,请考虑每个文档案例:

如果要更改的文档如下所示:

{
    "_id": "efgh",
    "name": "Jerry"
}
Run Code Online (Sandbox Code Playgroud)

然后是这样的更新语句:

db.collection.update(
    { "_id": "efgh" },
    { "$push": { "myArray": { "field1": "abc", "field2": "def" } } }
)
Run Code Online (Sandbox Code Playgroud)

结果如下:

{
    "_id": "efgh",
    "name": "Jerry",
    "myArray": [
        {
            "field1": "abc",
            "field2": "def"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

因此创建了数组并附加了新项.

如果您的文档已经有这样的数组:

{
    "_id": "abcd",
    "name": "Tom",
    "myArray": [
        {
            "field1": "",
            "field2": ""
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

而你基本上做同样的声明:

db.collection.update(
    { "_id": "abcd" },
    { "$push": { "myArray": { "field1": "abc", "field2": "def" } } }
)
Run Code Online (Sandbox Code Playgroud)

然后将新文档内容附加到现有数组:

{
    "_id": "abcd",
    "name": "Tom",
    "myArray": [
        {
            "field1": "",
            "field2": ""
        },
        {
            "field1": "abc",
            "field2": "def"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您的原始文档具有命名字段但它不是数组,则如下所示:

{
    "_id": "efgh",
    "name": "Jerry",
    "myArray": 123
}
Run Code Online (Sandbox Code Playgroud)

然后通过在查询条件中进行测试并使用$set相反来确保它不是数组:

db.collection.update(
    { "_id": "efgh", "myArray.0": { "$exists": false } },
    { "$set": { "myArray": [{ "field1": "abc", "field2": "def" }] } }
)
Run Code Online (Sandbox Code Playgroud)

这将安全地覆盖不是数组的元素(点符号"myArray.0"表示第一个数组元素,这不是真的),其中包含一个包含内容的新数组.结果与原始结果相同:

{
    "_id": "efgh",
    "name": "Jerry",
    "myArray": [
        {
            "field1": "abc",
            "field2": "def"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)


Yat*_*ath 5

$Push是实现这一目标所需的。如果 myArray 已经存在,则 $push 会将 newObject 插入其中(类似于 STACK 数据结构操作)。如果 myArray 不存在,它将创建字段“myArray”作为键,并将 newObject 插入其中(类似于$Set oprtaion )

考虑下面的另一个示例文档:

{
_id : "abcd"
myArray:[
{
  field1:"mango",
  field2:"apple"
}
       ]
}
Run Code Online (Sandbox Code Playgroud)

现在让我们将以下对象插入其中:

var newObject = {field1:"example1" , field2:"exmaple2"};
Run Code Online (Sandbox Code Playgroud)

询问 :

db.collection.update({_id:"abcd"},{"$push":{myArray: newObject }});
Run Code Online (Sandbox Code Playgroud)

执行上述查询后,结果如下:

{
    _id : "abcd"
    myArray:[
    {
      field1:"mango",
      field2:"apple"
    },
    {
      field1:"example1" , 
      field2:"exmaple2"
    }
           ]
    }
Run Code Online (Sandbox Code Playgroud)

现在让我们考虑另一个示例,其中文档中不存在“myArray”键:

{
_id:"efg"
}
Run Code Online (Sandbox Code Playgroud)

所以让我们插入以下对象:

 var newObject2 = { field1 : "exp2" , field2 : "exp1" }
Run Code Online (Sandbox Code Playgroud)

询问 :

 db.collection.update({_id:"efg"},{"$push":{myArray: newObject2 }});
Run Code Online (Sandbox Code Playgroud)

上述 UPDATE 操作的结果如下:

 {
   _id : "efg"
   myArray : [ 
   { 
    field1 : "exp2" , 
    field2 : "exp1"
  }
          ]
}
Run Code Online (Sandbox Code Playgroud)