对应用于MongoDB中数组元素中每个项的函数进行排序



我有一个对象,它包含一个字段,其中有一个字段的度量值列表:

public class TestObject {
[BsonElement("graph")]
public List<Measurement> Graph { get; set; }
}
public class Measurement {
[BsonRequired]
[BsonElement("magnitude")]
public uint Magnitude { get; set; }
[BsonRequired]
[BsonElement("measured_on")]
public DateTime MeasuredOn { get; set; }
}

我正在尝试为MongoDB编写一个查找操作,该操作将检索按Graph属性上的m个最近的Magnitude属性之和排序的前N个TestObject条目。我目前的尝试如下:

var findOptions = new FindOptions<TestObject> {
Limit = N,
Sort = new SortDefinitionBuilder<TestObject>()
.Descending(p => p.Graph.OrderByDescending(r => r.MeasuredOn)
.Take(M)
.Sum(r => r.Magnitude)),
Projection = new ProjectionDefinitionBuilder<TestObject>()
.Slice(p => p.Graph, 0, N),
};
IMongoCollection<TestObject> collection = GetCollection();
var cursor = await collection.FindAsync(FilterDefinition<TestObject>.Empty,
findOptions, 
token)
.ConfigureAwait(false);
return await cursor.ToListAsync(token).ConfigureAwait(false);

然而,这目前正在抛出一个NotSupportedException:

System.NotSupportedException: 
The method OrderByDescending is not supported in the expression tree: 
{document}{graph}.OrderByDescending(r => r.MeasuredOn).

从这一点我可以理解,我尝试将LINQ表达式与MongoDB混合使用是行不通的,但我不知道如何使这个查询工作。如有任何帮助,我们将不胜感激。

认为Find接口不可能实现。然而,Aggregation接口可以这样做:

let docLimit = 1;
let graphLimit = 2;
db.collection.aggregate(
[
{
$project: {
_id: 1,
graph: 1
}
},
{
$unwind: "$graph"
},
{
$sort: { "graph.measured_on": -1 }
},
{
$group: {
_id: "$_id",
graph: { $push: "$graph" },
}
},
{
$set: { graph: { $slice: ["$graph", graphLimit] } }
},
{
$set: { graphSum: { $sum: "$graph.magnitude" } }
},
{
$sort: { graphSum: -1 }
},
{
$limit: docLimit
},
{
$unset: "graphSum"
}
])

也不要认为您可以将上面的聚合查询转换为强类型的c查询。您只需要将一个json字符串传递给驱动程序。

最新更新