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

Sort on function applied to each item in array element in 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 编写一个查找操作,它将检索前 N TestObject 个条目,这些条目按 Graph属性。我目前的尝试是这样的:

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 字符串传递给驱动程序即可。