I have a document with sub-documents and sub-sub-documents
{
"ClockID" : "fd51b6e0-5b81-49ab-8424-71fd768281b2",
"ClockName" : "AAA-TEST123-002",
"FilesList" : [{
"FileName" : "AAA-TEST123-002.mpg",
"FileLocationHistory" : [{
"FullPath" : "192.168.32.166/Ingestion",
"AllowDeleteOnCancel" : false,
"_id" : "565b7343-9dc5-4916-a788-0f392fce2502"
}],
"_id" : "15b54499-a0be-4278-82ed-58c82c13bd40",
}],
"_id" : ObjectId("510164d0a63cfa2250fd6d19"),
"_t" : "ClockRecord"
This is mapped to 3 classes:
public class ClockRecord : IDatabaseRecord
{
public ClockRecord()
{
FilesList = new List<ClockRecordFile>();
}
public string ClockID { get; set; }
public string ClockName { get; set; }
public List<ClockRecordFile> FilesList { get; set; }
public BsonObjectId _id { get; set; }
}
public class ClockRecordFile
{
public ClockFileRecord()
{
FileLocationHistory = new List<ClockFileLocationHistoryRecord>();
}
public string FileName { get; set; }
public string FileStatus { get; set; }
public string _id { get; set; }
}
public class ClockFileLocationHistoryRecord
{
public string FullPath { get; set; }
public bool AllowDeleteOnCancel { get; set; }
public string _id { get; set; }
}
And I use this method to retrieve the top level document:
public List<ClockRecord> GetClocksByID(string id)
{
var collection = MongoDatabase.GetCollection<ClockRecord>(Collections.Clocks);
var query = from e in collection.AsQueryable()
where e._id == ObjectId.Parse(id)
select e;
var clocks = query.ToList();
return clocks;
}
So,
when I want to update a sub-document in the FilesList array I use this:
public void UpdateClocksFilesRecord(string collectionName, ClockFileRecord clockFileRecord, BsonObjectId clockDocumentID)
{
var mongoCollection = MongoDatabase.GetCollection<ClockRecord>("Clocks");
var update = Update.Set("FilesList.$", BsonDocumentWrapper.Create<ClockFileRecord>(clockFileRecord));
var modeResult = mongoCollection.Update(
Query.And(
Query.EQ("_id", clockDocumentID),
Query.ElemMatch("FilesList", Query.EQ("_id", clockFileRecord._id))
),
update, UpdateFlags.Upsert
);
}
This works fine.
When I want to update a sub-sub-document in the FilesList.FileLocationHistory array I use this:
public void UpdateClockFilesLocationRecord(string collectionName, ClockFileLocationHistoryRecord clockFileLocationHistory, BsonObjectId clockDocumentID, string clockFileDocumentID)
{
var mongoCollection = MongoDatabase.GetCollection<ClockRecord>("Clocks");
var update = Update.Set("FilesList.$.FileLocationHistory", BsonDocumentWrapper.Create<ClockFileLocationHistoryRecord>(clockFileLocationHistory));
var modeResult = mongoCollection.Update(
Query.And(
Query.EQ("_id", clockDocumentID),
Query.EQ("FilesList._id", clockFileDocumentID)
),
update, UpdateFlags.Upsert
);
}
This updates the sub-sub-document OK but when I run GetClocksByID() to deserialise the document I get an error:
“An error occurred while deserializing the FilesList property of class ClockRecord:
An error occurred while deserializing the FileLocationHistory property of class ClockFileRecord:
Expected element name to be ‘_t’, not FullPath.”
Now the FileLocationHistory document did not have a property _t before the edit and it de-serialized just fine (the top level document does have _t).
Why is the driver expecting the document to have an _t property after the update?
And what should I do about it?
Additional:
The only change I can see is that the FileLocationHistory document changes the order of fields after the update. I don’t know if this relevant.
OK, the problem is that my Update code is turning FileLocationHistory from an array of documents into an object.
I have posted this as a new question:
“Why does my Update to a sub document remove the array nature of sub document”