MongoDB 的 push 和 root 的 C# 等价物是什么?
What is the C# equivalent of push and root for MongoDB?
我有一 collection 人。我正在尝试为每个名字找到最年长的人。我能够使用 mongoDB 控制台命令
实现该结果
db.People.aggregate([
{ '$sort': { 'Name': 1, 'Age': -1 } },
{
'$group': {
'_id': '$Name',
'docs': { '$push': '$$ROOT' },
}
},
{
'$project': {
'top_one': {
'$slice': ['$docs', 1]
}
}
} ])
对于 C# 驱动程序,这相当于什么?我在
方面遇到了特别的麻烦
'docs': { '$push': '$$ROOT' },
这是我当前的 C# 查询:
collection.Aggregate(aggArgs)
.SortByDescending(x => x.Age)
.Group(x => x.Name, x => new {
Name = x.First().Name,
FavoriteColor = x.First().FavoriteColor,
FavoriteFood = x.First().FavoriteFood
}).ToListAsync().Result;
它的工作方式与我的 mongo 控制台命令的工作方式很接近,但我真的不喜欢构建匿名 object。我更愿意做 Group(x => x.Name,x => x.First())
,但是不支持 "First()" 的抛出和异常。我认为部分问题在于我的 Person 类型没有 ID,因此 _id 被放在实际的 mongo 文档中(由 mongo 自动插入)。当它试图返回类型时,它无法进行直接映射。
那么,考虑到查询的两个版本,我如何在 C# 中恢复我的完整类型而不必拼出每个字段?
这是 MongoDB 驱动程序的一项功能。它不接受简单的 First(),它背后需要一些东西。那是我通过调试看到的。所以你应该继续使用 First()... 或者你可以直接查询你的 json:
var result = collection.Aggregate()
.Group(new JsonProjectionDefinition<People>(@" {
'_id': '$Name',
'docs': { '$push': '$$ROOT' },}"))
.Project<TopOne>(new JsonProjectionDefinition<BsonDocument>(@"{
'top_one': {
'$slice': ['$docs', 1]
} }"))
.ToList();
Maksim 帮助了我很多。这是我最终得到的结果,以便得到与我输入时相同的类型:
collection.Aggregate(aggArgs)
.SortByDescending(x => x.Age)
.Group(new JsonProjectionDefinition<Person>(@"{
'_id': '$Name',
'docs': { '$push': '$$ROOT'}
}"))
.Project<BsonDocument>(new JsonProjectionDefinition<BsonDocument>(@"{
'top': { '$slice': ['$docs', 1] }
}"))
.Unwind<BsonDocument>(new StringFieldDefinition<BsonDocument>("top"))
.ReplaceRoot(new BsonValueAggregateExpressionDefinition<BsonDocument, BsonDocument>(@"$top"))
.Project<Person>(new JsonProjectionDefinition<BsonDocument>(@"{
_id: 0
}"))
.ToList();
我有一 collection 人。我正在尝试为每个名字找到最年长的人。我能够使用 mongoDB 控制台命令
实现该结果db.People.aggregate([
{ '$sort': { 'Name': 1, 'Age': -1 } },
{
'$group': {
'_id': '$Name',
'docs': { '$push': '$$ROOT' },
}
},
{
'$project': {
'top_one': {
'$slice': ['$docs', 1]
}
}
} ])
对于 C# 驱动程序,这相当于什么?我在
方面遇到了特别的麻烦'docs': { '$push': '$$ROOT' },
这是我当前的 C# 查询:
collection.Aggregate(aggArgs)
.SortByDescending(x => x.Age)
.Group(x => x.Name, x => new {
Name = x.First().Name,
FavoriteColor = x.First().FavoriteColor,
FavoriteFood = x.First().FavoriteFood
}).ToListAsync().Result;
它的工作方式与我的 mongo 控制台命令的工作方式很接近,但我真的不喜欢构建匿名 object。我更愿意做 Group(x => x.Name,x => x.First())
,但是不支持 "First()" 的抛出和异常。我认为部分问题在于我的 Person 类型没有 ID,因此 _id 被放在实际的 mongo 文档中(由 mongo 自动插入)。当它试图返回类型时,它无法进行直接映射。
那么,考虑到查询的两个版本,我如何在 C# 中恢复我的完整类型而不必拼出每个字段?
这是 MongoDB 驱动程序的一项功能。它不接受简单的 First(),它背后需要一些东西。那是我通过调试看到的。所以你应该继续使用 First()... 或者你可以直接查询你的 json:
var result = collection.Aggregate()
.Group(new JsonProjectionDefinition<People>(@" {
'_id': '$Name',
'docs': { '$push': '$$ROOT' },}"))
.Project<TopOne>(new JsonProjectionDefinition<BsonDocument>(@"{
'top_one': {
'$slice': ['$docs', 1]
} }"))
.ToList();
Maksim 帮助了我很多。这是我最终得到的结果,以便得到与我输入时相同的类型:
collection.Aggregate(aggArgs)
.SortByDescending(x => x.Age)
.Group(new JsonProjectionDefinition<Person>(@"{
'_id': '$Name',
'docs': { '$push': '$$ROOT'}
}"))
.Project<BsonDocument>(new JsonProjectionDefinition<BsonDocument>(@"{
'top': { '$slice': ['$docs', 1] }
}"))
.Unwind<BsonDocument>(new StringFieldDefinition<BsonDocument>("top"))
.ReplaceRoot(new BsonValueAggregateExpressionDefinition<BsonDocument, BsonDocument>(@"$top"))
.Project<Person>(new JsonProjectionDefinition<BsonDocument>(@"{
_id: 0
}"))
.ToList();