这是我的MongoDB数据结构:
public class Part : ICloneable
{
string _id;
ObservableCollection<DataElement> PartData;
ObservableCollection<DataElement> SensorData;
}
public class DataElement: ICloneable
{
string description;
string[] values;
}
使用 Linq,我想读取 SensorData、PartData 和 ResultData 元素上的所有 Part$projected
/reduce 以及特定的描述。
例:
Part{
_id: id1,
PartData[
{description: "des1", values: "val1"},
{description: "des2", values: "val2"}
],
SensorData[
{description: "des3", values: "val5"},
{description: "des4", values: "val2"},
{description: "des5", values: "val2"}
]}
应该在具有描述"DES2"、"DES4"和"DES5"的所有元素上投影/缩减,以便读取的数据看起来像
Part{
_id: id1,
PartData[
{description: "des2", values: "val2"}
],
SensorData[
{description: "des4", values: "val2"},
{description: "des5", values: "val2"}
]}
每个描述都是唯一的,但并非每个部件都包含所有描述。
有没有一个简单的解决方案可以在没有任何$unwind/选择许多的情况下做到这一点?类似的东西
Select(p => p.PartData[] where p.PartData.Description == specifiedDescription),
p => p.SensorData[] where p.SensorData.Description == specifiedDescription))
但包括完整的数组元素,同时排除其他元素以及 PartData 和 SensorData?
编辑: 在Veeram回答后,我尝试实现以下内容:
parts = db.GetCollection<Part>("Part");
var pipeline = parts.Aggregate()
.Project(p => new
{ PartData = p.PartData.Where(d => d.Description == specifiedDescription),
SensorData = p.SensorData.Where(s => s.Description == specifiedDescription)
}) ;
var query = pipeline.ToEnumerable().AsQueryable();
var returnParts = new ObservableCollection<Part>(query);
但这会导致pipeline
成为匿名IAggregateFluent<'a>
而不是IAggregateFluent<Part>
,这使得query
成为匿名IQueryable<'a
>,因此在插入query
作为ObservableCollection<Part>()
构造函数的参数时导致编译错误"无法从匿名IQueryable<'a
>转换为IQueryable<Part>
"。
如果没有$select
变量不再是匿名的,而是类<Part>
的,并且不会发生编译错误。显然,$select
更改了聚合的类。
如何解决此错误?我的想法是在不生成新类的情况下进行$project
,而是重置当前类<Part>
的某些字段,但这如何实现?
可以在$project
聚合管道的阶段中使用$filter
运算符。
var pipeline =
collection.
Aggregate()
.Project(
p => new {
PartData= p.PartData.Where(d => d.Description == specifiedDescription),
SensorData= p.SensorData.Where(s=> s.Description == specifiedDescription)
}
);