场景
有两张表,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 => 保存
对于$page
的switches
来讲,该数组维护的数据类型是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数组的元素切片为前三个元素:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。