I have an application with the following document structure:
{
"_id" : ObjectId("123456789"),
"DateStamp" : ISODate("2021-11-20T00:00:00.000Z"),
"Codes" : [
{
"Code" : "1000",
"Ident" : "ABC"
},
{
"Code" : "1001",
"Ident" : "DEF"
},
{
"Code" : "1002",
"Ident" : null
}
]
}
For each day it exists such a document, with several codes.
The application needs sometime to upsert the codes for the actual day. The upsert rules are as following:
- if the code is already existing for the day and the ident is not null → do nothing
- if the code is already existing for the day and the ident is null → update the ident
- if the code is not existing → insert new code+ident
Here is a sample application code:
public class MyDoc
{
public List<CodeInfo> Codes { get; set; }
[BsonElement("DateStamp")]
[BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
public DateTime DateStamp { get; set; }
}
public class CodeInfo
{
public string Code { get; set; }
public string Ident { get; set; }
}
Main()
{
...
var actUtcDt = DateTime.UtcNow;
var dateStr = actUtcDt.ToString("ddMMyyyy");
var dayParsed = DateTime.ParseExact(dateStr, "ddMMyyyy", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
var dayParsedUtc = dayParsed.ToUniversalTime();
var newCodes = new List<CodeInfo>
{
new CodeInfo { Code = "1000", Ident = "ABC2" },
new CodeInfo { Code = "1002", Ident = "EFGH" },
new CodeInfo { Code = "1003", Ident = "MNOP" }
};
var myNewDoc = new MyDoc { DateStamp = dayParsedUtc, Codes = newCodes };
UpsertMyDoc(myNewDoc);
...
}
void UpsertMyDoc(MyDoc myDoc)
{
IMongoCollection<MyDoc> mongoCollection = ...;
var filterMyDocBuilder = Builders<MyDoc>.Filter;
var updateMyDocBuilder = Builders<MyDoc>.Update;
var dtUtc = myDoc.DateStamp;
var filterDate = filterMyDocBuilder.Eq(x => x.DateStamp, dtUtc);
// only set on insert
var updateDef = updateMyDocBuilder
.SetOnInsert(p => p.DateStamp, dtUtc)
.SetOnInsert(p => p.Codes, myDoc.Codes)
;
var options = new UpdateOptions { IsUpsert = true };
var updRes = await mongoCollection.UpdateOneAsync(filterDate, updateDef, options);
var dayAvailable = updRes.IsAcknowledged && updRes.MatchedCount == 1 && updRes.UpsertedId == null;
if (dayAvailable)
{
....???
}
}
It is expected that 1000 is ignored, 1002 updates the ident and 1003 is inserted. The “upserted” document should now look like this:
{
"_id" : ObjectId("123456789"),
"DateStamp" : ISODate("2021-11-20T00:00:00.000Z"),
"Codes" : [
{
"Code" : "1000",
"Ident" : "ABC"
},
{
"Code" : "1001",
"Ident" : "DEF"
},
{
"Code" : "1002",
"Ident" : "EFGH"
},
{
"Code" : "1003",
"Ident" : "MNOP"
}
]
}
How can this be achieved with mongodb, in c# ?