如何在MongoDB的Find方法中嵌套Where实现复杂查询,过滤匹配语言的产品数据
错误原因
MongoDB .NET 驱动的Find方法要求传入的过滤表达式必须返回bool类型,你当前代码中Find参数内写的p.ProductValues.Where(pv => pv.Lang == lang)返回的是IEnumerable<ProductValue>集合类型,无法隐式转换为bool,因此触发了类型转换报错。
实现方案
你的需求包含两层逻辑:筛选出包含指定语言嵌套数据的产品,同时过滤每个产品的嵌套列表仅保留指定语言内容。推荐使用服务端聚合查询实现,避免冗余数据传输:
// 定义过滤条件:筛选ProductValues中存在对应语言条目的Product var matchFilter = Builders<Product>.Filter.ElemMatch(p => p.ProductValues, pv => pv.Lang == lang); // 定义投影规则:返回基础字段 + ProductValues中仅保留匹配语言的条目 var projection = Builders<Product>.Projection .Include(p => p.Id) .Include(p => p.Price) .Include(p => p.Date) .ElemMatch(p => p.ProductValues, pv => pv.Lang == lang); // 执行聚合查询 return Collection.Aggregate() .Match(matchFilter) .Project<Product>(projection) .ToList();
如果你的数据量很小,也可以先查询符合条件的产品,再在内存中过滤嵌套列表:
// 先过滤出符合条件的Product,这里把原来的Where换成Any就能解决最初的类型报错 var products = Collection.Find(p => p.ProductValues.Any(pv => pv.Lang == lang)).ToList(); // 内存层面过滤嵌套列表 foreach(var product in products) { product.ProductValues = product.ProductValues.Where(pv => pv.Lang == lang).ToList(); } return products;
注意事项
如果使用第一种聚合投影方案,需要给Product类添加无参构造函数,方便MongoDB驱动反序列化查询结果。
内容的提问来源于stack exchange,提问作者Azad Samedov
相关产品推荐
相关产品推荐

