Vraag Upserting in Mongo DB en het Id-probleem


Ik heb een probleem bij het upgraden naar mongo db met de officiële C # -driver.

public abstract class AggregateRoot
{
    /// <summary>
    /// All mongoDb documents must have an id, we specify it here
    /// </summary>
    protected AggregateRoot()
    {
        Id = ObjectId.GenerateNewId();
    }

    [BsonId]
    public ObjectId Id { get; set; }
}

Mijn entiteiten hebben al de ID-s, maar ik moest de mongo-specifieke ID maken om te laten werken, omdat alle documenten in een verzameling er een zouden moeten hebben. Nu ontvang ik een nieuwe entiteit in mijn systeem een ​​nieuwe Mongo-ID wordt gegenereerd en ik krijg de mongo kan _id of a document old niet veranderen uitzondering. Is er wat aan de hand?

Laat me het ontwerp een beetje beschrijven. Alle entiteiten die zouden zijn   opgeslagen als documenten werden overgenomen van AggregateRoot die de   id-generatie erin. Elk subdocument had zijn ID gegenereerd   automatisch en ik had hier geen probleem mee. De id in AggregateRoot   is geïntroduceerd om het probleem te corrigeren bij het ophalen van gegevens uit   MongoCollection to List en de generatie werd geïntroduceerd, dus de id-s   zijn verschillend. Nu kunnen we die ID-generatie verplaatsen om methoden op te slaan   omdat de nieuwe entiteit voor update een nieuwe id-generatie had. Maar het   zou betekenen dat elke ontwikkelaar in het team de ID's niet mag vergeten   in een repository die riskant is. Het zou leuker zijn om gewoon de id te negeren   dan in kaart brengen van mongo als het mogelijk is en niet te hebben   AggregateRoot-klasse helemaal


14
2017-09-02 12:06


oorsprong


antwoorden:


Het lijkt erop dat u de. Expliciet instelt Id waarde voor zowel inserts als updates. Dat is prima voor inserts, alle nieuwe objecten hebben een _id waarde, maar voor updates mag u de waarde van niet wijzigen _id op een bestaand document nadat het is gemaakt.

Probeer het niet in te stellen Id waarde helemaal. Als u geen waarde opgeeft voordat u deze invoegt, gebruikt het stuurprogramma ingebouwd IdGenerator klassen om een ​​nieuwe _id-waarde te genereren, dus als het een ObjectId-type is, gebruikt het de .id ObjectIdGenerator. Dan werken zowel je inserts als updates goed.


8
2017-09-02 13:17



Ik ben een soortgelijk probleem tegengekomen. Ik wilde documenten verbeteren met behulp van de officiële C # -driver. Ik had een klasse als deze:

public class MyClass
{
    public ObjectId Id { get; set; }
    public int Field1 { get; set; }
    public string Field2 { get; set; }
}

In console zou ik schrijven: db.collection.update({Field1: 3},{Field1: 3, Field2: "value"}) en het zou werken. In C # schreef ik:

collection.Update(Query.EQ("Field1", 3),
                Update.Replace(new MyClass { Field1 = 3, Field2 = "value" }),
                UpdateFlags.Upsert);

en het werkte niet! Omdat het stuurprogramma een lege id bevat in de updateaanduiding en wanneer ik een tweede document toevoeg met een andere waarde van Field1-uitzondering E11000 duplicate key error index wordt gegooid (in dit geval probeert Mongo een document in te voegen met _id dat al bestaat in db).

Toen ik _id zelf maakte (zoals topicstarter), ben ik dezelfde uitzondering tegengekomen (mongo cannot change _id of a document) op opgaande objecten met de bestaande waarde van Field1.

Oplossing is om Id-eigenschap op attribuut te markeren [BsonIgnoreIfDefault] (en niet initialiseren). In dit geval laat het stuurprogramma het veld _id in de updateaanduiding weg en genereert MongoDb de ID als dit nodig is.


56
2017-11-29 13:28