如何使用upsert将文档批量插入数组

时间:2019-04-09 07:58:30

标签: mongodb mongodb-query mongodb-.net-driver

我正试图将数百万个文档批量写入MongoDB,但找不到合适的方法。有许多示例可以插入一个对象,更新许多对象,但是它们效率不高或不适合我的情况。我要插入一个对象(如果不存在),否则更新该对象。听起来很简单,但问题出在文档内部的数组中。

我尝试拉然后推到traits数组,但是花了大约30分钟来更新2万个联系人。我还尝试插入(如果不存在)然后更新,但它的效果也很差。

这是一个示例Contact对象:

{
    "_id" : ObjectId("5cac414930114a1526c28940"),
    "externalId" : "1",
    "traits" : [ 
        {
            "_id" : ObjectId("5cac41e136ed1033f0a54878"),
            "trait_Id" : ObjectId("5cab5be130114a1526c26118"),
            "value" : "Firstname 1"
        }, 
        {
            "_id" : ObjectId("5cac41e136ed1033f0a54879"),
            "trait_Id" : ObjectId("5cab5bf930114a1526c26124"),
            "value" : "Lastname 1"
        }
    ]
}

还有一个trait_id来自的Trait文档。特征文档样本。

{
    "_id" : ObjectId("5cab5be130114a1526c26118"),
    "name" : "Firstname",
    "type" : "string",
    "sequence_number" : 1
}

我想将Trait文档插入到Contact的traits数组中:

{
    "trait_Id" : ObjectId("5cab5be130114a1526c26118"),
    "value" : "John"
}

这是我使用的代码:

public void BulkUpdate(List<Contact> contacts)
{
    var contactBulkList = new List<WriteModel<BsonDocument>>();
    contacts.ForEach(contact =>
    {
        contact.Traits.ForEach(trait =>
        {

            //Pull trait
            var filter = new BsonDocument("externalId", contact.ExternalId);

            var update = Builders<BsonDocument>.Update.PullFilter("traits", Builders<BsonDocument>.Filter.Eq("trait_Id", new ObjectId(trait.TraitId)));
            contactBulkList.Add(new UpdateOneModel<BsonDocument>(filter, update));

            //Push trait
            var push = Builders<BsonDocument>.Update.Push("traits", trait);
            var model = new UpdateOneModel<BsonDocument>(filter, push) { IsUpsert = true };
            contactBulkList.Add(model);
        });
    });
    GetCollectionWithName(typeof(Contact).Name).BulkWrite(contactBulkList, new BulkWriteOptions { IsOrdered = false });
}

我希望将“名字1”更新为“约翰”。如果没有与trait_id匹配的特征,则应将其插入traits数组。如何使用C#Mongo驱动程序实现此目的?

选项:

  1. 拉动特征,然后再推(不好)
  2. 创建具有特征并覆盖的文档(这意味着我会丢失不在批量写入中的特征)
  3. 查找每个联系人的特征。检查C#代码中的新值。如果存在,请发送给他们更新声明。如果不发送它们,则插入语句。 (这可能很合理,但是如果一个联系人具有200个特质该怎么办)
  4. 还有什么??

0 个答案:

没有答案