MongoDB C#collection.Save vs Insert + Update

时间:2011-11-21 21:25:51

标签: mongodb mongodb-.net-driver

来自C#文档:

  

Save方法是Insert和Update的组合。如果文档的Id成员具有值,则假定它是现有文档并且保存调用文档上的更新(设置Upsert标志以防万一它实际上是新文档)。

我正在我的所有域对象继承的基类中手动创建我的ID。所以我的所有域对象在插入MongoDB时都有一个ID。

问题是,我应该使用collection.Save并保持我的界面简单,否则这实际上会导致Save-call(带有Upsert标志)的一些开销,我应该使用collection.Insert和Update吗? / p>

我在想的是Save方法首先调用Update,然后发现我的新对象首先不存在,然后调用Insert。我错了吗?有没人测试过这个?

注意:我使用InsertBatch插入批量数据,因此在这种情况下,大数据块无关紧要。

修改,跟进

我写了一个小测试,以确定调用Update with Upsert标志是否有一些开销,所以Insert可能会更好。原来它们以相同的速度运行。请参阅下面的测试代码。 MongoDbServer和IMongoDbServer是我自己的通用接口,用于隔离存储设施。

IMongoDbServer server = new MongoDbServer();
Stopwatch sw = new Stopwatch();
long d1 = 0;
long d2 = 0;
for (int w = 0; w <= 100; w++)
{
    sw.Restart();
    for (int i = 0; i <= 10000; i++)
    {
        ProductionArea area = new ProductionArea();
        server.Save(area);
    }
    sw.Stop();
    d1 += sw.ElapsedMilliseconds;
    sw.Restart();
    for (int i = 0; i <= 10000; i++)
    {
        ProductionArea area = new ProductionArea();
        server.Insert(area);
    }
    sw.Stop();
    d2 += sw.ElapsedMilliseconds;
}
long a1 = d1/100;
long a2 = d2/100;

1 个答案:

答案 0 :(得分:12)

Save方法将两次前往服务器。

启发式是:如果正在保存的文档没有_id字段的值,则为其生成一个值,然后调用Insert。如果正在保存的文档的_id值为非零值,则使用Upsert标志调用Update,在这种情况下,由服务器决定是执行插入还是更新。

我不知道Upsert是否比Insert更昂贵。我怀疑它们几乎是一样的,真​​正重要的是无论哪种方式都是单一的网络往返。

如果您知道这是一个新文档,您也可以调用Insert。调用InsertBatch way 比调用多个单独的Insert更高效。所以绝对更喜欢InsertBatch来保存。