javascript - 使用 Mongoose ArrayFilters 更新嵌套子文档时出错
问题描述
我有一个想要更新嵌套子文档的 Mongoose 集合。
基本设置是这样的:
- 父条目(地图)
- 其中包含一组孩子(阶段)
- 每个孩子由一个或多个孙子组成(步骤)。
我希望能够找到一个孙子并更新它。我的方法是找到包含孙子的父(地图),然后更新它。
这些是我的简化模式:
const phaseSchema = new mongoose.Schema(
{
name: String,
color: String,
steps: [
new mongoose.Schema(
{
name: String,
body: String,
entry: {
type: mongoose.SchemaTypes.ObjectId,
ref: 'entry',
default: null
}
},
{ timestamps: false }
)
]
},
{ timestamps: false, _id: true }
)
const mapSchema = new mongoose.Schema(
{
name: String,
phases: [phaseSchema]
},
{ timestamps: false }
)
export const Map = mongoose.model('map', mapSchema)
我正在尝试使用 ArrayFilters 来查找和更新子文档,但没有运气:
req.body = {
map_id: 'some_mongoose_id',
step_id: 'some_other_mongoose_id'
}
const newEntryId = 'a_new_mongoose_id'
// Find the parent (Map) and update it
const UpdatedMap = await Map.update(
{ _id: req.body.map_id },
{
$set: {
'phases.$[i].steps.$[j].entry': mongoose.Types.ObjectId(newEntryId)
}
},
{
arrayFilters: [
{
'i.steps._id': mongoose.Types.ObjectId(req.body.step_id)
},
{
'j._id:': mongoose.Types.ObjectId(req.body.step_id)
}
]
}
)
这会引发以下错误:
错误:在架构中找不到路径“phases.0.steps.0._id:”
巧合的是,我尝试更新的阶段和步骤都在索引 0 处。
如果我换出 arrayFilters 并对索引进行硬编码,就像这样$set: {'phases.0.steps.0.entry': mongoose.Types.ObjectId(newEntryId)'}
,它可以工作。
我究竟做错了什么?
解决方案
这i
是导致错误的原因,它也是多余的。没有它,嵌套的 arrayFilter 将根据需要工作。
const UpdatedMap = await Map.update(
{ _id: req.body.map_id },
{
$set: {
'phases.steps.$[j].entry': mongoose.Types.ObjectId(newEntryId)
}
},
{
arrayFilters: [
{
'j._id:': mongoose.Types.ObjectId(req.body.step_id)
}
]
}
)
推荐阅读
- c# - 网页上的 Google 登录,在 ASP.NET 后端验证的令牌,没有使用客户端密码?
- javascript - 无法创建远程会话 - Eclipse - Appium
- react-native - react-native-firebase/admob rewardedAd.load() 第二次不工作
- web - Stack Overflow 配置文件中“标题”的用途是什么?
- swift - Swift 开发 pod
- flutter - 只有当上面的内容适合屏幕时,我才能在 Flutter 中对齐屏幕底部的区域。如果不是,所有内容都应该是可滚动的
- mysql - MySQL Node JS:选择查询结果到数组并在其他函数中使用这个数组
- docker - 在 go get 期间使用 docker alpine 会产生“未知修订”错误
- java - Android Java - OnCreate 中的竞争条件与两个观察者并制作列表
- node.js - VSCode 错误地将 Sequelize findOne 和 findAll 的返回类型推断为 any