2010-08-12 124 views
6

我知道这个问题之前已经被问过,但那是一个不同的场景。 我想有一个集合是这样的:有没有办法用单个查询插入列表?

{ 
    "_id" : ObjectId("4c28f62cbf8544c60506f11d"), 
    "pk": 1, 
    "forums": [{ 
     "pk": 1, 
     "thread_count": 10, 
     "post_count": 20, 
    }, { 
     "pk": 2, 
     "thread_count": 5, 
     "post_count": 24, 
    }] 
} 

我想要做的是一个UPSERT“论坛”项目,增加柜台或者如果它不存在添加的项目。

例如做这样的事情(我希望这是有道理的):

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, 
    }] 
} 

我一定能够使它在三个步骤:

  1. 用一个新项目插入整个集合
  2. addToSet论坛项目到列表
  3. 增量论坛项目计数器与位置操作

这就是说:

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的

回答

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}}) 
+0

是的,我想通了。不管怎么说,还是要谢谢你。 – Germano 2010-11-05 10:28:30

相关问题