MongoDB的push和root的C#等价物是什么?

时间:2017-01-27 20:36:52

标签: c# .net mongodb mongodb-query mongodb-.net-driver

我有一群人。我试图为每个名字找到最老的人。我可以使用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控制台命令所做的工作,但我真的不喜欢构建一个匿名对象。我更愿意做Group(x => x.Name,x => x.First()),但抛出和异常“First()”不受支持。我相信部分问题是我的Person类型没有ID,因此_id被放在实际的mongo文档上(插入时由mongo自动)。当它试图返回类型时,它无法进行直接映射。

因此,考虑到查询的两个版本,如何在不必拼出每个字段的情况下将我的完整类型恢复为C#?

2 个答案:

答案 0 :(得分:3)

这是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();

答案 1 :(得分:2)

马克西姆在那里给了我很多东西。这是我最终得到的结果,以便像我投入的那样获得相同的类型:

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();