Tengo un objeto que contiene un campo con una lista de medidas para uno de los campos:
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; } } Estoy tratando de escribir una operación de búsqueda para MongoDB que recupere las primeras N entradas de TestObject ordenadas por la suma de los M atributos de Magnitude más recientes en el atributo Graph . Mi intento actual se ve así:
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); Sin embargo, esto actualmente arroja una NotSupportedException :
System.NotSupportedException: The method OrderByDescending is not supported in the expression tree: {document}{graph}.OrderByDescending(r => r.MeasuredOn).A partir de esto, puedo entender que mi intento de mezclar expresiones LINQ con MongoDB no funcionará, pero no puedo entender cómo hacer que esta consulta funcione. Cualquier ayuda sería apreciada.
no creo que sea posible lograrlo con la interfaz de Find . sin embargo, la interfaz de Aggregation puede hacerlo así:
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" } ])Tampoco crea que puede traducir la consulta de agregación anterior a una consulta c# fuertemente tipada. solo tendrá que pasar una cadena json al controlador.