通过相似的对象值使用 findOneAndUpdate 更新对象
Update objects with findOneAndUpdate by similar object value
我正在尝试更新文档值,如果它们已经存在于集合中,如果它们对于特定对象键具有相同的值。
比如我有以下文件-
{ eventType: "A", browsers: [ { name: "Chrome", count: 10 } ]}
{ eventType: "B", browsers: [ { name: "Chrome", count: 2 } ]}
{ eventType: "A", browsers: [ { name: "Chrome", count: 5 }, { name: "Safari", count: 8 } ]}
最后,我希望集合按事件类型合并文档,并按浏览器名称值合并浏览器聚合(在下面的示例中,“Chrome”计数合并为 15) ;如果值不存在,将新对象添加到 browsers 数组(在下面的示例中,将“Safari”对象添加到现有浏览器聚合):
{ eventType: "A", browsers: [ { name: "Chrome", count: 15 }, { name: "Safari", count: 8 } ]}
{ eventType: "B", browsers: [ { name: "Chrome", count: 2 } ]}
如果需要,我想使用以下查询来更新和插入新文档,但我不确定如何进行浏览器聚合。
const doc = { eventType: "A", browsers: [ { name: "Chrome", count: 5 }, { name: "Safari", count: 8 } ]}
collection.findOneAndUpdate({
eventType: doc.eventType
}, {
// What to do in here?
}, {
upsert: true,
new: true
})
是否有使用自定义函数的选项,例如 collection.aggregate 用例中的 $accumulator
?
P.S - 我在这段代码中使用猫鼬
不可能在一条语句中执行此操作,因为您的目标是通过 eventType 将文档收集到一组新文档中,但是您可以通过合并聚合来完成大部分工作:
[{$unwind: {
path: '$browsers',
includeArrayIndex: 'b',
preserveNullAndEmptyArrays: true
}}, {$group: {
_id: '$eventType',
eventType: {
$first: '$eventType'
},
browsers: {
$addToSet: '$browsers'
}
}}, {$addFields: {
grouped: 1
}}, {$merge: {
into: 'so_example',
on: '_id',
whenMatched: 'replace',
whenNotMatched: 'discard'
}}]
这将需要第二个过程来 a) 删除未合并的文档和减少浏览器数组的内容,以便每个浏览器都有计数的总和。
显然,不可能在单个原子查询中执行此类操作。
我 'solved' 通过更改模式来实现,因此键将是动态的,例如
{
browsers: {
Chrome: {
count: 15
}
}
}
使用此实现,我根据必须插入的新文档动态构建 findOneAndUpdate 的 update
部分。
我正在尝试更新文档值,如果它们已经存在于集合中,如果它们对于特定对象键具有相同的值。
比如我有以下文件-
{ eventType: "A", browsers: [ { name: "Chrome", count: 10 } ]}
{ eventType: "B", browsers: [ { name: "Chrome", count: 2 } ]}
{ eventType: "A", browsers: [ { name: "Chrome", count: 5 }, { name: "Safari", count: 8 } ]}
最后,我希望集合按事件类型合并文档,并按浏览器名称值合并浏览器聚合(在下面的示例中,“Chrome”计数合并为 15) ;如果值不存在,将新对象添加到 browsers 数组(在下面的示例中,将“Safari”对象添加到现有浏览器聚合):
{ eventType: "A", browsers: [ { name: "Chrome", count: 15 }, { name: "Safari", count: 8 } ]}
{ eventType: "B", browsers: [ { name: "Chrome", count: 2 } ]}
如果需要,我想使用以下查询来更新和插入新文档,但我不确定如何进行浏览器聚合。
const doc = { eventType: "A", browsers: [ { name: "Chrome", count: 5 }, { name: "Safari", count: 8 } ]}
collection.findOneAndUpdate({
eventType: doc.eventType
}, {
// What to do in here?
}, {
upsert: true,
new: true
})
是否有使用自定义函数的选项,例如 collection.aggregate 用例中的 $accumulator
?
P.S - 我在这段代码中使用猫鼬
不可能在一条语句中执行此操作,因为您的目标是通过 eventType 将文档收集到一组新文档中,但是您可以通过合并聚合来完成大部分工作:
[{$unwind: {
path: '$browsers',
includeArrayIndex: 'b',
preserveNullAndEmptyArrays: true
}}, {$group: {
_id: '$eventType',
eventType: {
$first: '$eventType'
},
browsers: {
$addToSet: '$browsers'
}
}}, {$addFields: {
grouped: 1
}}, {$merge: {
into: 'so_example',
on: '_id',
whenMatched: 'replace',
whenNotMatched: 'discard'
}}]
这将需要第二个过程来 a) 删除未合并的文档和减少浏览器数组的内容,以便每个浏览器都有计数的总和。
显然,不可能在单个原子查询中执行此类操作。 我 'solved' 通过更改模式来实现,因此键将是动态的,例如
{
browsers: {
Chrome: {
count: 15
}
}
}
使用此实现,我根据必须插入的新文档动态构建 findOneAndUpdate 的 update
部分。