1

I am trying to write a migration script between an older version and the newer version of a model, we have a reactive migration system which checks loaded models version to see if its up to date. If not it will apply a migration delta to the model and persist it back in its new form. In this new version all that has changed is that now one of the child objects has a key called i.e "SomeNewKey".

So here is how the data looks for the old version of the model:

{
    SomeModel: 
    {
        _id: <some-guid>,
        Version: 1.0.1
        Name: <some-string>,
        SomeArrayData: [
            {
                Name: <some-string>,
                DateCreated: <some-date>
            },
            {
                Name: <some-string>,
                DateCreated: <some-date>
            },
            {
                Name: <some-string>,
                DateCreated: <some-date>
            }
        ]       
    }
}

And here is how it should be for the new version:

{
    SomeModel: 
    {
        _id: <some-guid>,
        Versio: 1.0.2
        Name: <some-string>,
        SomeArrayData: [
            {
                Name: <some-string>,
                DateCreated: <some-date>,
                SomeNewKey: <some-default-guid>
            },
            {
                Name: <some-string>,
                DateCreated: <some-date>,
                SomeNewKey: <some-default-guid>
            },
            {
                Name: <some-string>,
                DateCreated: <some-date>,
                SomeNewKey: <some-default-guid>
            }
        ]       
    }
}

So as you can see I basically need to get the model, then go through each sub document in SomeArrayData and insert a new key with a default empty guid.

I first of all tried:

var findQuery = Query.EQ("_id", id);
var updateQuery = Update.Set("SomeArrayData.SomeNewKey", Guid.Empty);
var result = collection.Update(findQuery, updateQuery, UpdateFlags.Multi);
if (result.Ok == false) { throw new Exception(result.ErrorMessage); }

However this kept blowing up on the write concern, and I couldn't find out much about that, so then I looked round and found articles like:

Updating an array of objects with a new key in mongoDB

Which seem to imply I need to do an aggregate call to do an unwind of the arrays, but I cannot find any examples of how to do this sort of thing in the C# driver, so can anyone point me in the right direction?

Community
  • 1
  • 1
Grofit
  • 17,693
  • 24
  • 96
  • 176
  • The aggregate example on that question has nothing to do with your solution. There is also no way to update all of the array members at once across all documents. Your best bet is to loop all documents in your collection via a find, manipulate the array/list members to contain the new key and then update each document individually with the changed array contents as a whole. The basic process is shown in JavaScript code on the answer I just up-voted on your referenced question, because it is essentially correct. – Neil Lunn Jun 11 '14 at 09:30
  • I dont need to update it across ALL documents, just a single instance of a document, as the migrations are done as and when someone loads a document. I originally did do it in code but I thought as I will end up doing a query anyway it may be better to just do it all in a query if it is possible. – Grofit Jun 11 '14 at 09:32
  • I don't think it would make sense to assign a GUID in a query since that will always change. Calculated fields based on the the values of other fields makes sense at run-time. Your question reads more like a requirement to add an additional field to your documents permanently. So if you have another intent then perhaps re-phrase your question. – Neil Lunn Jun 11 '14 at 09:54
  • A system works off a given model, that model has to be of a certain version. Currently the version is 1.0.2, however previous stored documents will contain the data in an incompatible version, so rather than doing pro-active migrations like we would on a relational DB we do it on a reactive based approach so when we load in the document we check its version and then migrate it to match the latest model schema and then persist it again. So it doesn't really matter if I am adding/removing keys/values nor does it matter what type those changes are, its just a change, the question is clear enough. – Grofit Jun 11 '14 at 10:02
  • Look at the long comment responses here. This information is not your question. If you edit your question to explain your real purpose then answers are more clear to define and arrive at. The body of "what you need" should not be in comments. I am commenting here because I could see that your intentions are not clearly stated and you need to fix your question. Please do so. It will help you. – Neil Lunn Jun 11 '14 at 10:08
  • I do not know what else needs to be cleared up, I want to change the document schema from A -> B permanently as you say. I clearly state the current document format, and the format I need it to now adhere to, I give you a link to someone who has same problem without the C# flavouring and I also explain how I am doing the update. There is very little room for interpretation as far as I can see, and all the comment responses here are you confusing the question with other queries and use-cases which do not apply. – Grofit Jun 11 '14 at 10:16

0 Answers0