如何使用C# MongoDB.Driver 2.10按Int字段的字符串值过滤文档
解决MongoDB.Driver按Int字段的字符串值过滤的问题
嘿,我明白你的困扰了!你遇到的问题核心在于:MongoDB.Driver的LINQ查询提供器没办法把你写的.AsString或者.ToString()这类客户端方法转换成MongoDB服务器能执行的查询语句,所以才会抛出那些错误。不过别担心,有几种方法能实现你要的“把Int类型字段转成字符串后匹配'1'”的需求。
方法一:使用$expr直接构建查询语句
这是最直接的方式,利用MongoDB的$expr操作符,在服务器端把Int字段转换成字符串再做匹配。你可以直接用BsonDocument来构建这个查询:
MongoClient dbClient = new MongoClient("mongodb://***"); IMongoDatabase db = dbClient.GetDatabase("***"); var collection = db.GetCollection<BsonDocument>("***"); // 构建过滤条件:将lockPolicyId转成字符串后等于"1" var filter = new BsonDocument("$expr", new BsonDocument("$eq", new BsonArray { new BsonDocument("$toString", "$lockPolicyId"), "1" } ) ); // 执行查询 var result = collection.Find(filter).FirstOrDefault(); Console.WriteLine(result);
这个写法的原理是让MongoDB服务器执行$toString操作(把Int类型的lockPolicyId转成字符串),然后和字符串"1"做相等匹配,完全在服务器端完成转换和过滤,不会有客户端方法不支持的问题。
方法二:使用聚合管道实现转换+过滤
如果你更倾向于用聚合的方式来处理,也可以通过聚合管道先添加一个字符串类型的字段,再进行过滤:
var result = collection.Aggregate() // 先确保字段存在(可选,避免处理无此字段的文档) .Match(Builders<BsonDocument>.Filter.Exists("lockPolicyId")) // 添加一个新字段lockPolicyIdStr,值为lockPolicyId的字符串形式 .AddFields(new BsonDocument("lockPolicyIdStr", new BsonDocument("$toString", "$lockPolicyId"))) // 过滤这个新的字符串字段等于"1"的文档 .Match(Builders<BsonDocument>.Filter.Eq("lockPolicyIdStr", "1")) .FirstOrDefault();
这个方法的好处是可以在后续的聚合步骤中继续使用转换后的字符串字段,如果还有其他需要字符串处理的逻辑会很方便。
为什么你之前的写法不行?
简单解释下报错原因:
- 第一种写法里的
a["lockPolicyId"].AsString是客户端的BsonValue属性,LINQ提供器没办法把这个属性访问转换成MongoDB服务器能理解的查询操作,所以会抛出运算符不匹配的错误。 - 第二种写法的
.ToString()同样是客户端方法,驱动明确不支持把这个方法转换成服务器端的操作,所以会提示“{document}{lockPolicyId}.ToString() is not supported”。
内容的提问来源于stack exchange,提问作者Royi Namir
相关产品推荐
相关产品推荐

