Mongodb Core problems

I’m using firely to create/read FHIR objects stored in the Atlas cloud. Things work fine in .net framework. Upgrading to .net Core and downloading the new drivers and serialize software, I am storing objects fine - - at least I see the FHIR objects correctly formed using Compass. When I read one of those objects as a bson document, now I get a bunch of junk (timestamp, machine, etc.) in what is returned which, of course, does not parse as a FHIR object. How do I get rid of the system generated data when reading a document with the new core driver ?

Hi Dennis! I’m a PM on the .NET team and happy to help. I understand you’re experiencing some issues with your reads following upgrading from .NET Framework to .NET Core. Could you share (1) a code snippet that reproduces the issue in .NET Core and (2) a snippet that worked fine in .NET Framework as well as the driver version, server version and TFMs you’re using in each case?

How do I attach a log file with the calls and returned data? There’s some kind of “3 links for new members” error when I try to copy the text into the reply.

Thanks.


You can attach files using the box in red. Alternatively you can use markup and paste the log file directly in here. For example:

var filter = Builders<Restaurant>.Filter
  .Eq(restaurant => restaurant.Name, "Bagels N Buns");
var restaurant = _restaurantsCollection.Find(filter).FirstOrDefault();
Console.WriteLine(restaurant);

New users aren’t allowed to upload files. See if you can follow this link to look at the file.

Here I create the document

var collection = Life.GetCollection<BsonDocument>(collectiontype);

resource = resource.Replace(q + "id" + q, q + "\_id" + q);

BsonDocument document = BsonDocument.Parse(resource);

collection.InsertOne(document);



Here is what got written:			

document.ToString()

"{ \"resourceType\" : \"MedicationStatement\", \"identifier\" : [{ \"system\" : \"rx number/branch\", \"value\" : \"367950\", \"assigner\" : { \"reference\" : \"BC000001BN\", \"type\" : \"Organization\" } }], \"status\" : \"active\", \"category\" : { \"coding\" : [{ \"system\" : \"http://www.whocc.no/atc\", \"code\" : \"C09AA05\" }, { \"system\" : \"Vigilance\", \"code\" : \"24080405\" }], \"text\" : \"ATC\" }, \"medicationCodeableConcept\" : { \"text\" : \"RAMIPRIL\" }, \"subject\" : { \"reference\" : \"180000193\", \"type\" : \"Person\" }, \"effectiveDateTime\" : \"2023-03-31T08:48:44+00:00\", \"dateAsserted\" : \"2023-03-31T08:48\", \"informationSource\" : { \"reference\" : \"XXAWE/91\", \"type\" : \"Practitioner\", \"display\" : \"MACHINERY    ALCOVE\" }, \"dosage\" : [{ \"sequence\" : 367950, \"text\" : \"Take.\", \"timing\" : { \"event\" : [\"2023-03-31T08:48\"], \"repeat\" : { \"boundsPeriod\" : { \"start\" : \"2023-03-31T08:48\", \"end\" : \"2023-05-30T08:48\" }, \"period\" : 10, \"periodUnit\" : \"d\"

} }, \"asNeededBoolean\" : false, \"route\" : { \"coding\" : [{ \"system\" : \"http://snomed.info/sct\", \"code\" : \"261665006\", \"display\" : \"po\" }], \"text\" : \"none\" }, \"doseAndRate\" : [{ \"doseQuantity\" : { \"value\" : 10, \"unit\" : \"MG\" }, \"rateQuantity\" : { \"unit\" : \"daily\" } }] }] }"

Here is what I see on Compass, which is CORRECT in both the old and new versions.

{

"\_id": {

"$oid": "64270173d513a771d2e3b5a2"

},

"resourceType": "MedicationStatement",

"identifier": [

{

"system": "rx number/branch",

"value": "367950",

"assigner": {

"reference": "BC000001BN",

"type": "Organization"

}

}

],

"status": "active",

"category": {

"coding": [

{

"system": "http://www.whocc.no/atc",

"code": "C09AA05"

},

{

"system": "Vigilance",

"code": "24080405"

}

],

"text": "ATC"

},

"medicationCodeableConcept": {

"text": "RAMIPRIL"

},

"subject": {

"reference": "180000193",

"type": "Person"

},

"effectiveDateTime": "2023-03-31T08:48:44+00:00",

"dateAsserted": "2023-03-31T08:48",

"informationSource": {

"reference": "XXAWE/91",

"type": "Practitioner",

"display": "MACHINERY    ALCOVE"

},

"dosage": [

{

"sequence": 367950,

"text": "Take.",

"timing": {

"event": [

"2023-03-31T08:48"

],

"repeat": {

"boundsPeriod": {

"start": "2023-03-31T08:48",

"end": "2023-05-30T08:48"

},

"period": 10,

"periodUnit": "d"

}

},

"asNeededBoolean": false,

"route": {

"coding": [

{

"system": "http://snomed.info/sct",

"code": "261665006",

"display": "po"

}

],

"text": "none"

},

"doseAndRate": [

{

"doseQuantity": {

"value": 10,

"unit": "MG"

},

"rateQuantity": {

"unit": "daily"

}

}

]

}

]

}

Here is where I read the document back in:

var collection = FHIRSubs.Life.GetCollection<BsonDocument>("MedicationStatement");

var meds = collection.Find(filterc).ToList();

//foreach (BsonDocument n in meds)

for (n = 0; n < meds.Count; n++)

{

ms = FHIRSubs.ReturnMed(meds[n]);

`				`\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_



Here is what comes back.				



meds[n]: monbdb driver v 4.0.30319	-- CORRECT

"{ \"\_id\" : ObjectId(\"64270173d513a771d2e3b5a2\"), \"resourceType\" : \"MedicationStatement\", \"identifier\" : [{ \"system\" : \"rx number/branch\", \"value\" : \"367950\", \"assigner\" : { \"reference\" : \"BC000001BN\", \"type\" : \"Organization\" } }], \"status\" : \"active\", \"category\" : { \"coding\" : [{ \"system\" : \"http://www.whocc.no/atc\", \"code\" : \"C09AA05\" }, { \"system\" : \"Vigilance\", \"code\" : \"24080405\" }], \"text\" : \"ATC\" }, \"medicationCodeableConcept\" : { \"text\" : \"RAMIPRIL\" }, \"subject\" : { \"reference\" : \"180000193\", \"type\" : \"Person\" }, \"effectiveDateTime\" : \"2023-03-31T08:48:44+00:00\", \"dateAsserted\" : \"2023-03-31T08:48\", \"informationSource\" : { \"reference\" : \"XXAWE/91\", \"type\" : \"Practitioner\", \"display\" : \"MACHINERY    ALCOVE\" }, \"dosage\" : [{ \"sequence\" : 367950, \"text\" : \"Take.\", \"timing\" : { \"event\" : [\"2023-03-31T08:48\"], \"repeat\" : { \"boundsPeriod\" : { \"start\" : \"2023-03-31T08:48\", \"end\" : \"2023-05-30T

08:48\" }, \"period\" : 10, \"periodUnit\" : \"d\" } }, \"asNeededBoolean\" : false, \"route\" : { \"coding\" : [{ \"system\" : \"http://snomed.info/sct\", \"code\" : \"261665006\", \"display\" : \"po\" }], \"text\" : \"none\" }, \"doseAndRate\" : [{ \"doseQuantity\" : { \"value\" : 10, \"unit\" : \"MG\" }, \"rateQuantity\" : { \"unit\" : \"daily\" } }] }] }"





meds[n]: .core from nuget current -- GARBAGE		



"{\"id\":{\"Timestamp\":1680277875,\"Machine\":13964199,\"Pid\":29138,\"Increment\":14923170,\"CreationTime\":\"2023-03-31T15:51:15Z\"},\"resourceType\":\"MedicationStatement\",\"identifier\":[{\"system\":\"rx number/branch\",\"value\":\"367950\",\"assigner\":{\"reference\":\"BC000001BN\",\"type\":\"Organization\"}}],\"status\":\"active\",\"category\":{\"coding\":[{\"system\":\"http://www.whocc.no/atc\",\"code\":\"C09AA05\"},{\"system\":\"Vigilance\",\"code\":\"24080405\"}],\"text\":\"ATC\"},\"medicationCodeableConcept\":{\"text\":\"RAMIPRIL\"},\"subject\":{\"reference\":\"180000193\",\"type\":\"Person\"},\"effectiveDateTime\":\"2023-03-31T08:48:44\\u002B00:00\",\"dateAsserted\":\"2023-03-31T08:48\",\"informationSource\":{\"reference\":\"XXAWE/91\",\"type\":\"Practitioner\",\"display\":\"MACHINERY    ALCOVE\"},\"dosage\":[{\"sequence\":367950,\"text\":\"Take.\",\"timing\":{\"event\":[\"2023-03-31T08:48\"],\"repeat\":{\"boundsPeriod\":{\"start\":\"2023-03-31T08:48\",\"end\":\"2023-05-30T08:48\"},\"period\":10,\

"periodUnit\":\"d\"}},\"asNeededBoolean\":false,\"route\":{\"coding\":[{\"system\":\"http://snomed.info/sct\",\"code\":\"261665006\",\"display\":\"po\"}],\"text\":\"none\"},\"doseAndRate\":[{\"doseQuantity\":{\"value\":10,\"unit\":\"MG\"},\"rateQuantity\":{\"unit\":\"daily\"}}]}]}"

Hi, @Dennis_Brox,

Just jumping in to help @Patrick_Gilfether1 understand the issue that you’ve encountered.

I see that you’ve inserted an ObjectId with value 64270173d513a771d2e3b5a2. ObjectId is a 12-byte identifier consisting of a timestamp, random value, and counter. In some implementations, the random value is a hash of the machine name and process ID (PID).

In EJSON, the ObjectId is represented as, which is what Compass displays:

{ $oid: "64270173d513a771d2e3b5a2" }

When you parse and insert this ObjectId into MongoDB, it gets inserted as an ObjectId with value 64270173d513a771d2e3b5a2. When it is read back into the C# application, it will be deserialized as an ObjectId. No surprises so far. And you in fact see exactly this value in _id from your .NET Framework v4.0.30319 application:

"{ \"\_id\" : ObjectId(\"64270173d513a771d2e3b5a2\")

But when you attempt the same from your .NET Core application, you see:

"{\"id\":{\"Timestamp\":1680277875,\"Machine\":13964199,\"Pid\":29138,\"Increment\":14923170,\"CreationTime\":\"2023-03-31T15:51:15Z\"}

Two points to note…

First the _id is now id, which is odd and unexpected. Given that you are working with BsonDocument objetcs, the driver would not be modifying the mapping of the BSON to change field names.

Second the “GARBAGE” is actually the properties that make up the ObjectId. The ObjectId.ToString() implementation displays ObjectId("64270173d513a771d2e3b5a2"). But that ObjectId corresponds to a Timestamp of 1680277875, Machine of 13964199, etc. The discrepancy might be as simple as whether your debugger is configured to display an object’s properties or its ToString() representation.

Hopefully that helps. If you continue to see discrepancies between the output from different versions of the driver, please provide a self-contained, runnable repro demonstrating the problem including the .NET version, .NET/C# Driver version, operating system, and any other relevant data so that we can investigate further.

Sincerely,
James

1 Like

Unfortunately you reply does not answer the question: “why does reading the bson document give a different result with .net 6 than framework”? Doing an insert without _id set, which is what I do, generates it in your database. When the bson document is read, I convert it to “id” so it parses in FHIR. I don’t want “how the _id is generated when I read the document”, I want the _id value returned as it is in framework. There is no “debugger” involved, just a c# program reading data. It is hard to believe that is no longer possible with .net core.

All documents in MongoDB require an _id. When you save an object without an _id, the .NET/C# Driver will generate one for you and update the object before sending the insert command to the database. I’m not sure what you mean by:

When the bson document is read, I convert it to “id” so it parses in FHIR.

How do you convert the _id to an id for FHIR. I assume that this is implemented in FHIRSubs.ReturnMed(meds[n]); but I don’t see the definition for this method in your sample code.

I tried parsing the provided ObjectId from JSON using .NET Framework 4.7.2, .NET Core 2.1, .NET Core 3.1, and .NET 6 using the following code:

using System;
using MongoDB.Bson;

public static class Program
{
    public static void Main()
    {
        var json = "{ _id: { '$oid': '64270173d513a771d2e3b5a2' } }";

        var bson = BsonDocument.Parse(json);

        Console.WriteLine(bson);
    }
}

The displayed result using any of those TFMs is:

{ "_id" : ObjectId("64270173d513a771d2e3b5a2") }

Saving this _id to the database and reading it back as a BsonDocument:

using System;
using MongoDB.Bson;
using MongoDB.Driver;

public static class Program
{
    public static void Main()
    {
        var client = new MongoClient();
        var db = client.GetDatabase("test");
        var coll = db.GetCollection<BsonDocument>("sample");

        var filter = Builders<BsonDocument>.Filter.Empty;
        coll.DeleteMany(filter);

        coll.InsertOne(new BsonDocument{{ "_id", ObjectId.Parse("64270173d513a771d2e3b5a2")}});

        var query = coll.Find(filter);
        foreach (var doc in query.ToList())
        {
            Console.WriteLine(doc);
        }
    }
}

This produces the same results on all TFMs as well:

{ "_id" : ObjectId("64270173d513a771d2e3b5a2") }

We have been unable to reproduce the issue that you are describing. Both from a JSON string and reading a document in from the database, .NET Framework 4.7.2 and .NET 6 both return the same, expected ObjectId. In order to investigate further, we require a self-contained, runnable repro of the issue that you are observing so that we can debug through it.

Sincerely,
James