我之前已经问过这个问题,但这是另一种情况。 我想要一个这样的集合:
{
"_id" : ObjectId("4c28f62cbf8544c60506f11d"),
"pk": 1,
"forums": [{
"pk": 1,
"thread_count": 10,
"post_count": 20,
}, {
"pk": 2,
"thread_count": 5,
"post_count": 24,
}]
}
我想要做的是插入一个“论坛”项目,递增计数器或添加一个项目(如果它不存在)。
例如做这样的事情(我希望它有意义):
db.mycollection.update({
"pk": 3,
"forums.pk": 2
}, {
"$inc": {"forums.$.thread_count": 1},
"$inc": {"forums.$.post_count": 1},
}, true)
并且:
{
"_id" : ObjectId("4c28f62cbf8544c60506f11d"),
"pk": 1,
"forums": [{
"pk": 1,
"thread_count": 10,
"post_count": 20,
}, {
"pk": 2,
"thread_count": 5,
"post_count": 24,
}]
},
{
"_id" : ObjectId("4c28f62cbf8544c60506f11e"),
"pk": 3,
"forums": [{
"pk": 2,
"thread_count": 1,
"post_count": 1,
}]
}
我可以分三步完成:
那就是说:
db.mycollection.update({pk:3}, {pk:3}, true)
db.mycollection.update({pk:3}, {$addToSet: {forums: {pk:2}}})
db.mycollection.update({pk:3, 'forums.pk': 2}, {$inc: {'forums.$.thread_counter': 1, {'forums.$.post_counter': 1}})
您是否意识到更有效的方法? TIA,Germano
答案 0 :(得分:10)
您可能已经发现,positional operator不能用于upserts:
位置运算符不能与
upsert
组合,因为它需要匹配的数组元素。如果您的更新导致插入,则“$”将字面上用作字段名称。
因此,您将无法在单个查询中获得所需的结果。
您 将文档的创建与计数器更新分开。您自己的解决方案正在走上正轨。它可以压缩为以下两个查询:
// optionally create the document, including the array
db.mycollection.update({pk:3}, {$addToSet: {forums: {pk:2}}}, true)
// update the counters in the array item
db.mycollection.update({pk:3, 'forums.pk': 2}, {$inc: {'forums.$.thread_counter': 1, 'forums.$.post_counter': 1}})