📜  仅当 addToSet 更新时才更新字段 (1)

📅  最后修改于: 2023-12-03 15:21:51.489000             🧑  作者: Mango

仅当 addToSet 更新时才更新字段

在MongoDB中,如果我们要向一个数组类型的字段中添加元素,我们可以使用 $addToSet 操作符。但是,有时我们只想在更新操作中添加了新元素时才更新字段,这时就需要用到 $addToSet 的特殊方法了。

$addToSet 的特殊方法

$addToSet 操作符有一个特殊方法:$each。它可以将一个数组中的每个元素添加到目标字段中。而且,如果目标字段中已经有了其中的某个元素,$each 方法会自动忽略掉。

举个例子,在一个文档中,有一个数组类型的字段 items,已经有了两个元素:'apple' 和 'banana'。现在我们要往这个字段中添加三个元素:'orange'、'banana' 和 'pear'。我们可以使用以下操作:

db.collection.update(
  { _id: ObjectId("5f07a5169318ba6aa2bb5f94") },
  { $addToSet: { items: { $each: ['orange', 'banana', 'pear'] } } }
)

这时,由于 'banana' 已经存在于 items 数组中,所以它不会被添加。而其他两个元素会被添加到数组尾部。

但是,如果我们想要在 items 数组中没有更新时,不更新整个文档,该怎么做呢?

仅当 addToSet 更新时才更新字段

在MongoDB 3.2版本以后,可以使用 $setOnInsert 操作符来实现这个需求。该操作符可以在更新时设置一个字段的值,但只有在文档被插入时才会生效。如果更新操作没有更新任何字段,那么就不会插入新文档。

对于我们上述的例子,我们可以这样写更新操作:

db.collection.update(
  { _id: ObjectId("5f07a5169318ba6aa2bb5f94") },
  { 
    $addToSet: { items: { $each: ['orange', 'banana', 'pear'] } },
    $setOnInsert: { createdAt: new Date() }
  }
)

这里,我们添加了一个 $setOnInsert 操作符,如果更新操作没有更新任何字段,那么会为这个文档插入一个新的字段 createdAt,它的值为当前时间戳。

总结

在MongoDB中,我们可以使用 $addToSet 操作符向一个数组类型的字段中添加元素。而 $addToSet 的特殊方法 $each 可以在一条更新语句中添加多个元素。对于一些特殊情况,我们可以使用 $setOnInsert 操作符来实现仅当 addToSet 更新时才更新字段的需求。