来自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;
答案 0 :(得分:12)
Save方法不将两次前往服务器。
启发式是:如果正在保存的文档没有_id字段的值,则为其生成一个值,然后调用Insert。如果正在保存的文档的_id值为非零值,则使用Upsert标志调用Update,在这种情况下,由服务器决定是执行插入还是更新。
我不知道Upsert是否比Insert更昂贵。我怀疑它们几乎是一样的,真正重要的是无论哪种方式都是单一的网络往返。
如果您知道这是一个新文档,您也可以调用Insert。调用InsertBatch way 比调用多个单独的Insert更高效。所以绝对更喜欢InsertBatch来保存。