我希望根据某些键获得不同的对象。以下是我在mongodb中的表现:
db.collection.aggregate(
[
{ $match: filter },
{
$group:
{
_id: distinctField,
value: { $first: "$$ROOT" } // taking any of group because we don't care
}
},
{ $replaceRoot : { newRoot: "$value" }}
]
)
它按预期工作。但后来我试着在C#中做到这一点:
public static IAggregateFluent<T> WhereDistinct<T, TKey>(this IMongoCollection<T> collection, FilterDefinition<T> filter, Expression<Func<T, TKey>> distinctField) =>
collection.Aggregate()
.Match(filter)
.Group(distinctField, items => new { Value = items.FirstOrDefault() }) // taking any of group because we don't care
.ReplaceRoot(arg => arg.Value);
我得到一个例外:
其他信息:System.Linq.Enumerable类型的FirstOrDefault 表达式树{document}中不支持.OrderByDescending(c =&GT; c.Version).FirstOrDefault()。
是否可以在不创建令人讨厌的BsonDocument
查询的情况下执行此操作?我知道我可以手动编写整个内容,但我想使用一些基于linq的方法。
答案 0 :(得分:0)
感谢@chridam,我知道没有clean way
来执行此操作。
但是,这种扩展方法可能会有所帮助。它完全是我在JS中编写的,但为C#提供了一些不错的API
public static IAggregateFluent<T> WhereDistinct<T, TKey>(this IMongoCollection<T> collection,
FilterDefinition<T> filter, Expression<Func<T, TKey>> distinctField) =>
collection.Aggregate()
.Match(filter)
.Group(new BsonDocument
{
{"_id", $"${((MemberExpression) distinctField.Body).Member.Name}"},
{"doc", new BsonDocument {{"$first", "$$ROOT"}}} // taking any of group because we don't care
})
.ReplaceRoot<T>("$doc");