当计数等于预期值时,是否将文档插入MongoDB?
仅当与特定查询匹配的文档数具有特定大小时,是否可以在MongoDB 4.2中插入/向上插入多个文档 例如: 假设我有一个当计数等于预期值时,是否将文档插入MongoDB?,mongodb,Mongodb,仅当与特定查询匹配的文档数具有特定大小时,是否可以在MongoDB 4.2中插入/向上插入多个文档 例如: 假设我有一个items集合,其中包含以下两个文档: { item: "ZZZ137", type="type1"} { item: "ZZZ138", type="type1"} { item: "ZZZ139", type="type1"} { item: "
items
集合,其中包含以下两个文档:
{ item: "ZZZ137", type="type1"}
{ item: "ZZZ138", type="type1"}
{ item: "ZZZ139", type="type1"}
{ item: "ZZZ140", type="type1"}
现在我想插入这两个文档:
{ item: "ZZZ137", type="type1"}
{ item: "ZZZ138", type="type1"}
{ item: "ZZZ139", type="type1"}
{ item: "ZZZ140", type="type1"}
但目前只有两项type1
在集合中(即type1
的计数等于2)
在MongoDB中,是否可以用一个命令来实现这一点
更新
为了进一步说明我的问题,让我们假设它支持条件。然后我想做类似的事情(不起作用的伪代码):
其中,
{$count:{type:“type”}:{$eq:2}
将是插入项ZZZ139
和ZZZ140
必须完成的查询,这可以通过使用或如果坚持在一个调用中执行此操作来实现,但是由于这两个运算符的逻辑和限制,效率非常低。我个人建议将其分为两个通话:
let typeTwoCount = await db.collection.countDocuments({type: "2"})
if (typeTwoCount === 2) {
await db.collection.insertMany(newItems)
}
现在我们可以使用$out
,但由于它会重新写入集合,我们必须通过管道将整个集合传输到$out
阶段,这很荒谬:
db.collection.aggregate([
{
$facet: {
typeTwo: [
{
$match: {
type: "2"
}
},
{
$count: "doc_count"
},
{
$addFields: {
newDocs: {
$cond: [
{$eq: ["$doc_count", 2]},
items,
[]
]
}
}
},
{
$unwind: "$newDocs"
},
{
$replaceRoot: {
newRoot: "$newDocs"
}
},
],
all: [
{
$match: {}
}
]
}
},
{
$addFields: {
merged: { $concatArrays: ["$all", "$typeTwo"]}
}
},
{
$unwind: "$merged"
},
{
$replaceRoot: {
newRoot: "$merged"
}
},
{
$out: "collection"
}
])
现在,$merge
的问题是以下限制:
输出集合不能与正在聚合的集合为同一集合
因此,我们可以采用与$out
管道类似的策略(对$merge
使用typeTwo
管道),但我们必须使用不同的非空虚拟集合启动聚合:
db.any_other_none_empty_collection.aggregate([
{
$limit: 1
},
{
$lookup: {
from: "collection",
let: {},
pipeline: [
{
$match: {
type: "2"
}
}
],
as: "all"
}
},
{
$addFields: {
doc_count: {$size: "$all"}
}
},
{
$addFields: {
newDocs: {
$cond: [
{$eq: ["$doc_count", 2]},
items,
[]
]
}
}
},
{
$unwind: "$newDocs"
},
{
$replaceRoot: {
newRoot: "$newDocs"
}
},
{
$merge: {
into: "collection"
}
}
])
我不明白你的意思。你能不能用一个简单的插页来阐述一下问题所在?另外,您目前如何使用多个命令执行此操作?添加了一个伪代码示例Mongo中没有条件插入,您必须将其拆分为两个调用。@TomSlabbaert那么这将回答我的问题,所以您可能希望将其添加为一个答案?我希望通过聚合管道实现这一点。我添加了一个包含所有选项的答案,我仍然建议将其分为两个调用,因为这是最“合理”的选项。