2017-01-27 22 views
3

我有一個人的集合。我正在嘗試爲每個名稱找到最老的人。我能夠使用mongoDB控制檯命令獲得該結果MongoDB的推和root的C#等價物是什麼?

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; 

它可以接近我的蒙戈控制檯命令做什麼,但我真的不喜歡的構建匿名對象。我寧願做Group(x => x.Name,x => x.First()),但拋出和不支持「First()」的異常。我相信問題的一部分是,我的Person類型沒有ID,所以_id放在實際的mongo文檔上(由mongo自動插入)。當它試圖回到這種類型時,它不能進行直接映射。因此,考慮到這兩個版本的查詢,如何在C#中恢復完整類型而不必拼出每個字段?

回答

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

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

幹得好!對我來說,這是一個有點蹩腳的方式,我會與mongo驅動程序做什麼,它允許t odo和linq休息,但這是你的選擇,我不知道你的數據有多大。 –

相關問題