场景

有两张表,page与switch。page的switches维护了与switch的_id映射,是典型的一对多关系。switch表的page字段与page表的_id字段是一对一关系。

当我删除掉switch表的一条数据时,应当删除对应page数据的switches内维护的_id。

代码是这么写的

// 根据id找出switch数据
const $switch = await this.switchModel.findById(id);
// 根据switch的page字段,取出page数据。
const $page = await this.pagesModel.findById( ($switch.page as any).id);

_.pull($page.switches,id)
$await page.save()
await this.switchModel.deleteById(id)

以为通过_.pull删除操作删除掉对应的字符串id即可。

但是没有成功。我又换了一种写法

// 根据id找出switch数据
const $switch = await this.switchModel.findById(id);
// 根据switch的page字段,取出page数据。
const $page = await this.pagesModel.findById( ($switch.page as any).id);

$page.switches = _.chain($page.switches).map(item => item.toString()).pull(id).value();
$await page.save()
await this.switchModel.deleteById(id)

通过这么操作,我将对应的switches通过map操作,都转成字符串id,在通过pull操作移除对应的_id。再去保存即可。

map转成字符串数组 => 移除id => 保存

对于$pageswitches来讲,该数组维护的数据类型是ObjectId类型。并不是一个id字符串。

更好的方法。

Update操作

对于保存数据。可以对于查询到的结果进行save操作。

但除了save操作,我们也可以使用updateXXX方法来更新数据。

对于第一节说到问题,我实际可以理解为不是对page文档的删除,而是更新操作。

相关的update api有

  • update
  • updateOne
  • updateMany
  • findByIdAndUpdate
  • findOneAndUpdate

save操作无法很好的解决问题的时候,就可以使用update操作来解决问题。

update操作要使用到MongoDB update operators

简单分类介绍一下。

update operators

字段

  • $currentDate 将字段的值设置为当前的时间
  • $inc 字段值增加指定的数量
  • $min $min指定的值小于当前的值才会发生更新
  • $max $max指定的值大于字段当前的值才会发生更新。 如果 $max: {name: 100},查询出name:120,不会被更新,如果99,80这种才会更新。
  • $mul 对指定的字段乘以指定的数量 $mul: {filedName: 2,} => 乘以2
  • $rename 字段名重命名 $rename: {"nmae": "name"}
  • $set 赋值 $set: {fieldName: value,"details.name": "zzzz"}
  • $setOnInsert 如果set操作发生了insert到表里,就会触发这个操作。一般用来设置一些默认值。
  • $unset 用来删除指定字段 {$unset: {quantity: "", instock: ""}} 删除这两个字段。

补充:

$set还可以修改数组中的值

db.products.update(
   { _id: 100 },
   { $set:
      {
        "tags.1": "rain gear",
        "ratings.0.rating": 2
      }
   }
)

数组

  • $ 充当占位 更新符合查询条件的第一个
  • $[] 充当占位,更新符合查询条件的所有元素
  • $[<identifier>]
  • $addToSet 如果不存在就添加,如果存在就不操作
  • $pop -1移除第一个元素,1移除最后的一个元素
  • $pull 移除一个指定的数据
  • $push 添加一个数据到数组中
  • $pullAll 移除所有符合条件的数据。

Modifiers

  • $each 可与$push和$addToSet一起用。添加多个值进去。 $addToSet: {tags: {$each: [1,2,3,4]}}
  • $position 修改$push操作符,指定的位置添加值
  • $slice 修改$push操作,用来限制更新的数组大小
  • $sort 修改$push操作符来重新排序存储在数组中的文档。 相当于更新以后根据$sort的配置在去重新~~~~排序。

$push: {

   scores: {
     $each: [ 80, 78, 86 ],
     $slice: -5
   }
 }

// 作的结果是将更新的scores数组的元素切片为最后5个元素

{
     $push: {
       scores: {
         $each: [ 100, 20 ],
         $slice: 3
       }
     }
}
   
   //该操作的结果是将更新的scores数组的元素切片为前三个元素:



最普通的一个
301 声望41 粉丝

永远不要做你擅长的事。


引用和评论

0 条评论