简体   繁体   中英

MongoDB C# driver: create document if not exists

I have some POCO of a type User and I have some concerns its properties going to change in future. I have a mongodb with Users collection to store the data. There's no uniqueness constraint on it, and I can't create one unfortunatelly. My app imports a bunch of old users from 3rd party archive source and I want to be able to write these users into mongo, but I don't want the duplicates and I don't want to replace user data on match because data in mongo is actual. Basically we can define user duplicate by matching filter like a.Username == b.Username && a.Email == b.Email or something similar, I don't want it to be relevant to this question, let's just say there's a way we can tell if users A and B are the same.

So it seems like my only option here is using upsert Update with SetOnInsert. In C# driver there's a method Builders<User>.Update.SetOnInsert<TField>(Expression<User,TField>, TField) but I will have to call it multiple times to enumerate all the properties. If these properties going to change in future, someone will have to update this method and I don't like it.

Is there a way to bypass this problem? Maybe by using reflecion and PropertyInfo or by working with BsonDocument directly? Or maybe I missing somethign and there's an easier way to do it? Thanks in advance.

Ok, so it wasn't that hard after all:

    var updates = new List<WriteModel<User>>();
    foreach (User appUser in users)
    {
        FilterDefinition<User> filter = Builders<User>.Filter.Eq(x => x.Username, appUser.Username) & ...

        var bsonDoc = appUser.ToBsonDocument();
        UpdateDefinition<User> updateDefinition = new UpdateDefinitionBuilder<User>().Unset("______"); // HACK: I found no other way to create an empty update definition
        foreach (var element in bsonDoc.Elements)
        {
            if (element.Name == "_id" || element.Value == BsonNull.Value)
                continue;
            updateDefinition = updateDefinition.SetOnInsert(element.Name, element.Value);
        }
        UpdateOneModel<User> update = new UpdateOneModel<User>(filter, updateDefinition) { IsUpsert = true };
        updates.Add(update);
    }
    MongoConnectionHelper.Database.GetCollection<User>("Users").BulkWrite(updates);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM