如何在C#中通过MongoDB驱动实现FHIR标识符同元素多条件过滤
解决MongoDB数组元素多条件匹配同一元素的C#实现
问题场景
使用C#、HL7.Fhir.R4和MongoDB驱动管理存储FHIR资源的MongoDB时,资源的identifier属性为数组类型,可存储多个标识符。原有的过滤写法会返回那些不同标识符元素分别满足条件的资源——比如过滤use=official且value=value2时,即使两个条件匹配数组中的不同元素,资源也会被返回,不符合“两个条件匹配同一个identifier元素”的需求。
原有过滤代码:
var builder = Builders<BsonDocument>.Filter; List<FilterDefinition<BsonDocument>> filters = new List<FilterDefinition<BsonDocument>>(); ... filters.Add(builder.Eq("SerializedResource.identifier.use", "official")); filters.Add(builder.Regex("SerializedResource.identifier.value", $"/^value2$/i"));
已知MongoDB原生查询写法(可实现需求):
{"SerializedResource.identifier":{ $elemMatch: {"use":"official", "value":/^value2$/i}}}
C#实现方案
在MongoDB C#驱动中,可通过ElemMatch方法实现上述原生查询的逻辑,以下是两种常见写法:
写法一:分步构建子条件
var builder = Builders<BsonDocument>.Filter; // 构建针对单个identifier元素的子过滤条件 var identifierSubFilter = builder.And( builder.Eq("use", "official"), builder.Regex("value", new BsonRegularExpression("^value2$", "i")) ); // 将子条件应用到identifier数组,要求至少一个元素满足所有子条件 var finalFilter = builder.ElemMatch("SerializedResource.identifier", identifierSubFilter); // 执行查询 var matchingResources = collection.Find(finalFilter).ToList();
写法二:链式调用简化
var builder = Builders<BsonDocument>.Filter; // 直接在ElemMatch中定义子条件 var finalFilter = builder.ElemMatch("SerializedResource.identifier", elem => elem.Eq("use", "official") .Regex("value", new BsonRegularExpression("^value2$", "i")) ); // 执行查询 var matchingResources = collection.Find(finalFilter).ToList();
关键说明
ElemMatch的核心作用是:指定数组字段,要求数组中至少存在一个元素同时满足所有子过滤条件,彻底解决了原写法中不同数组元素分别匹配条件的问题。- 正则表达式需使用
BsonRegularExpression类型,而非直接传入字符串形式的正则(如/^value2$/i),避免被当作普通字符串匹配。
内容的提问来源于stack exchange,提问作者Milton Calderon
相关产品推荐
相关产品推荐

