【问题标题】:Push object into array if the array exists otherwise create the array with object in MongoDB如果数组存在则将对象推送到数组中,否则在 MongoDB 中使用对象创建数组
【发布时间】:2015-08-02 09:37:41
【问题描述】:

我收集了这样的文档:

{
    _id : "abcd",
    name : "Tom",
    myArray : [
        {
            field1 : "",
            field2 : ""
        }
    ]
},
{
    _id : "efgh",
    name : "Jerry"
}

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

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

{
    _id : "abcd",
    name : "Tom",
    myArray : [
        {
            field1 : "",
            field2 : ""
        },
        {
            // new object
        }
    ]
}

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

{
    _id : "efgh",
    name : "Jerry"
    myArray : [
         {
              // new object
         }
    ]
}

我怎样才能做到这一点?

【问题讨论】:

  • 你想做什么?将“efgh”中的“myArray”设置为与“abcd”相同的内容?或者你想将一个新的数组项推送到“abcd”和“efgh”?您的问题上有一个Edit 链接,您可以在其中添加详细信息以明确您的意图。
  • @BlakesSeven ,修改问题希望你理解...
  • 仍然不清楚这里的“elseif”是什么意思。您是要更新“两个”文档,还是只选择更新“一个”文档?
  • 不,我不想同时更新这两个文档。一次只更新一个文档。
  • 你在这里尝试过什么吗?我猜不是因为你会看到当你 $push 一个数组到一个不存在的文档时会发生什么,而是它只是创建了数组。如果存在现有数组,则会附加新文档。因此,要么您根本没有尝试过,要么您的问题中仍然缺少一些关于您真正想做的事情。

标签: mongodb mongodb-query


【解决方案1】:

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

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

{
    "_id": "efgh",
    "name": "Jerry"
}

然后是这样的更新语句:

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

结果如下:

{
    "_id": "efgh",
    "name": "Jerry",
    "myArray": [
        {
            "field1": "abc",
            "field2": "def"
        }
    ]
}

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

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

{
    "_id": "abcd",
    "name": "Tom",
    "myArray": [
        {
            "field1": "",
            "field2": ""
        }
    ]
}

而你的声明基本相同:

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

然后将新的文档内容追加到现有数组中:

{
    "_id": "abcd",
    "name": "Tom",
    "myArray": [
        {
            "field1": "",
            "field2": ""
        },
        {
            "field1": "abc",
            "field2": "def"
        }
    ]
}

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

{
    "_id": "efgh",
    "name": "Jerry",
    "myArray": 123
}

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

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

这将使用包含您的内容的新数组安全地覆盖不是数组的元素(点表示法“myArray.0”表示第一个数组元素,这是不正确的)。结果和原来一样:

{
    "_id": "efgh",
    "name": "Jerry",
    "myArray": [
        {
            "field1": "abc",
            "field2": "def"
        }
    ]
}

【讨论】:

  • 你能用$addToSet代替$push吗?它会检查数组是否包含完全相同的json文档吗?
【解决方案2】:

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

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

{
_id : "abcd"
myArray:[
{
  field1:"mango",
  field2:"apple"
}
       ]
}

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

var newObject = {field1:"example1" , field2:"exmaple2"};

查询:

db.collection.update({_id:"abcd"},{"$push":{myArray: newObject }});

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

{
    _id : "abcd"
    myArray:[
    {
      field1:"mango",
      field2:"apple"
    },
    {
      field1:"example1" , 
      field2:"exmaple2"
    }
           ]
    }

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

{
_id:"efg"
}

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

 var newObject2 = { field1 : "exp2" , field2 : "exp1" }

查询:

 db.collection.update({_id:"efg"},{"$push":{myArray: newObject2 }});

上述UPDATE操作的结果如下:

 {
   _id : "efg"
   myArray : [ 
   { 
    field1 : "exp2" , 
    field2 : "exp1"
  }
          ]
}

【讨论】:

  • 如果没有具有该 ID 的文档不可用,我们想自己添加一个新文档怎么办?
  • @Rahul_Dabhi 您找到问题的答案了吗?我希望能够做到这一点。
猜你喜欢
  • 2017-05-10
  • 1970-01-01
  • 2019-09-15
  • 2021-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
相关资源
最近更新 更多