couchbaselabs / Linq2Couchbase

A Language Integrated Query (LINQ) provider for the Couchbase .NET SDK
Apache License 2.0
95 stars 46 forks source link

Incorrect N1QL generated when doing string comparisons using Fhir API #213

Open jeffrymorris opened 6 years ago

jeffrymorris commented 6 years ago

Note: Fhir is a specification for sharing health care records electronically.

A Linq2Couchbase user observes:

"FHIR has a special way it serializes objects into JSON. This works fine for reading and writing, but is complicated when searching. For example, when an extension with a FhirString value is serialized, it becomes a “valueString” property name:

new Models.Extension("https://fhir.app.localhost.net/Extension/ProjectName", 
                 new Models.FhirString("EBCD"));

When serialized it looks like this:

   {
     "url": "https://fhir.app.localhost.net/Extension/ProjectName",
      "valueString": "EBCD"
   }

The problem is when trying to search for that, here’s what the LINQ expression becomes:

device => device.Extension.Any(x => x.Url == "https://fhir.app.localhost.net/Extension/ProjectName" && x.Value == new Models.FhirString("EBCD

The N1QL generated looks like this:

SELECT `Extent1`.* FROM `FhirBucket` as `Extent1` WHERE (`Extent1`.`resourceType` = 'Device') AND ANY `Extent2` IN `Extent1`.`extension` SATISFIES ((`Extent2`.`url` = 'https://fhir.app.localhost.net/Extension/ProjectName') AND (`Extent2`.`value` = EBCD)) END LIMIT 100

Notice how it’s searching on the property Extent2.value because it doesn’t know how to change that to Extent2.valueString which is how the JSON is actually stored. I suspect this is because the object FhirString is on the right hand side of the equal sign whereas the change from value to valueString needs to happen on the left hand side of the equal sign."

I am not sure if this can be resolved at the Linq layer, since its really an effect of how Fhir wraps .NET strings with FhirString objects without actually changing the Fhir API.

jeffrymorris commented 6 years ago

There are two reasons why this won't work:

@brantburnett any thoughts?

brantburnett commented 6 years ago

@jeffrymorris

I'm not going to say that support for this is impossible, but it's a pretty specific edge case. I think it would require creating a pretty in-depth extension framework that would allow the query generator to be extended to account for the non-standard serialization pattern. Then, an FHIR-specific extension would be needed.

To me, the much simpler solution would be to store objects in Couchbase using a more basic, POCO-based serialization method. Then they could be queried freely, and something like AutoMapper could be used to convert them to the more specific types between the Data Access Layer and the Business Logic Layer. Of course, this may or may not be feasible for the project in question, depending on development rules and document compatibility requirements.