2015-01-08 52 views
2

有沒有辦法找到mongo db中具有最高計算值的文檔?使用c#驅動程序在mongodb中查找具有最高計算值的文檔

我有一個數組屬性,它由int的1-5組成。我想找到平均值最高的文檔。

像這樣使用常規的LINQ:

var entityWithCalculatedMax = collection.OrderByDescending(x => x.Grade.Sum()/x.Grade.Count()).First();  

有什麼建議?

(我想直接在數據庫中做到這一點,因爲我不想要檢索的所有文件,以獲得該文件)

回答

4

不幸的是,這不能做使用LINQ語法。使用canonic聚合語法更容易(也更具體),因爲它在the official "Aggregation Pipeline" documentation中有記錄。

示例輸入:

{ _id: 1, Grades: [ 1, 1 ] } 
{ _id: 2, Grades: [ 2, 3, 4 ] } 
{ _id: 3, Grades: [ 5 ] } 

的想法是具有在聚合管線四個步驟:

  1. 開卷每個Grades陣列:對於每一個文檔,這會創建Ñ其中n是每個文檔具有單一等級的等級數:

    結果:

    { _id: 1, Grades: 1 } 
    { _id: 1, Grades: 1 } 
    { _id: 2, Grades: 2 } 
    { _id: 2, Grades: 3 } 
    { _id: 2, Grades: 4 } 
    { _id: 3, Grades: 5 } 
    
  2. 集團由ID文件,彙總成績的)的平均財產(你的計算)和b)一個新的等級屬性,以恢復我們的數組:

    結果:

    { _id: 1, Average: 1.0, Grades: [ 1, 1 ] } 
    { _id: 2, Average: 3.0, Grades: [ 2, 3, 4 ] } 
    { _id: 3, Average: 5.0, Grades: [ 5 ] } 
    
  3. 排序由大道文件憤怒。

    結果:與上面相同,因爲它已經以某種方式排列。

  4. 限制爲1個文檔,因爲您只需要第一個結果。

我們可以把這一對JSON和執行它針對我們的分貝:

db.gradeDocs.aggregate(
    [ 
     { $unwind: "$Grades" }, 
     { 
      $group: { 
       _id: "$_id", 
       Average: { $avg: "$Grades" }, 
       Grades: { $push: "$Grades" } 
      } 
     }, 
     { $sort: { "Average": 1 } }, 
     { $limit: 1 } 
    ] 
) 

好了,現在我們如何能做到這一點使用C#的驅動程序?語法是有點冗長,但它本質上是同樣的事情:

var aggregateArgs = new AggregateArgs(); 
aggregateArgs.Pipeline = 
    new[] 
    { 
     new BsonDocument("$unwind", "$Grades"), 
     new BsonDocument("$group", 
      new BsonDocument 
      { 
       {"_id", "$_id"}, 
       {"Average", new BsonDocument("$avg", "$Grades")}, 
       {"Grades", new BsonDocument("$push", "$Grades")}, 
      }), 
     new BsonDocument("$sort", new BsonDocument("Average", 1)), 
     new BsonDocument("$limit", 1), 
    }; 

var resultId = collection 
    .Aggregate(aggregateArgs) 
    .Single()["_id"] 
    .AsObjectId; 
+0

尼斯解釋+1 – Disposer

+0

非常有幫助!謝謝! – martenolofsson

相關問題