更新或附加到 mongo 中的子集合 [英] Update or append to a subcollection in mongo
问题描述
我有一个包含子集合的集合.在一个请求中,如果不存在匹配项,我想更新子集合中的记录或附加到它.作为奖励,我还希望此更新是合并而不是覆盖.
I have a collection containing a subcollection. In one request, I would like to update a record in the subcollection or append to it if a match doesn't exist. For a bonus point I would also like this update to be a merge rather than an overwrite.
一个粗略的例子:
// Schema
{
subColl: [
{
name: String,
value: Number,
other: Number,
},
];
}
// Existing record
{
_id : 123,
subColl: [
{name: 'John',
value: 10,
other: 20}
]
}
// example
const update = { _id: 123, name: 'John', other: 1000 };
const { _id, name, other } = update;
const doc = await Schema.findById(_id);
const idx = doc.subColl.findIndex(({ name: nameInDoc }) => nameInDoc === name);
if (idx >= 0) {
doc.subColl[idx] = { ...doc.subColl[idx], other };
} else {
doc.subColl.push({ name, other });
}
doc.save();
目前我可以通过拉取记录并手动执行更新/追加来实现此结果,但我假设使用纯 mongo 查询实现它会快得多.
Currently I can achieve this result by pulling the record, and doing the update/append manually but I am assuming that achieving it with a pure mongo query would be much faster.
我试过了:
Schema.findOneAndUpdate(
{ _id: 123, 'subColl.name': 'John' },
{ $set: { 'subColl.$': [{ name: 'John', other: 1000 }] } }
)
但这不会处理追加行为,也不会将对象与现有记录合并,而是完全覆盖它.
but this won't handle the append behaviour and also doesn't merge the object with the existing record, rather it overwrites it completely.
推荐答案
我不确定在单个查询中是否有任何直接的方法可以做到这一点,
I am not sure is there any straight way to do this in single query,
$cond
检查名称是否在subColl
数组中,- true 条件,需要与现有对象合并,
$map
迭代循环,检查条件是否匹配条件,然后使用$mergeObjects
<将新数据对象与当前对象合并/li> - 假条件,需要使用
$concatArrays
连接数组、当前
subColl
数组和新对象$cond
to check name is insubColl
array,- true condition, need to merge with existing object,
$map
to iterate loop, check condition if matches condition then merge new data object with current object using$mergeObjects
- false condition, need to concat arrays, current
subColl
array and new object using$concatArrays
const _id = 123;
const update = { name: 'John', other: 1000 };
Schema.findOneAndUpdate(
{ _id: _id },
[{
$set: {
subColl: {
$cond: [
{ $in: [update.name, "$subColl.name"] },
{
$map: {
input: "$subColl",
in: {
$cond: [
{ $eq: ["$$this.name", update.name] },
{ $mergeObjects: ["$$this", update] },
"$$this"
]
}
}
},
{ $concatArrays: ["$subColl", [update]] }
]
}
}
}]
)
这篇关于更新或附加到 mongo 中的子集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!