2011-06-15 52 views
31

最小值你怎麼做的如何找到MongoDB中

SELECT 
    MIN(Id) AS MinId 
FROM 
    Table 
MongoDB中

相當。它看起來像我將不得不使用MapReduce,但我找不到任何示例顯示如何執行此操作。

謝謝。

回答

55

您可以使用sortlimit組合來模擬min

> db.foo.insert({a: 1}) 
> db.foo.insert({a: 2}) 
> db.foo.insert({a: 3}) 
> db.foo.find().sort({a: 1}).limit(1) 
{ "_id" : ObjectId("4df8d4a5957c623adae2ab7e"), "a" : 1 } 

sort({a: 1})是在a場的上升(最低優先)排序,然後我們只返回第一個文件,這將是該字段的最小值。

編輯:請注意,這是寫在mongo外殼,但你可以使用適當的驅動程序方法從C#或任何其他語言做同樣的事情。

+5

注意:您可能希望在指數{A:1}對於任何大型數據集。 – 2011-06-15 17:42:04

+2

這仍然是獲得最小值的最佳方式嗎? – clifgray 2015-01-21 01:26:58

+2

您現在可以使用Aggregate框架來實現此結果。從wanghao看到下面的答案。 db.myCollection.aggregate( [ { $組: { _id:{}, minPrice:{$分鐘: 「$價格」}} } ] ); – Waqas 2016-08-09 14:56:45

8

只是想展示如何用官方的c#驅動程序(因爲關於mongodb csharp的問題)完成一個改進:我只加載一個字段,但不是整個文檔,如果我只想找到該字段的最小值。下面是完整的測試案例:

[TestMethod] 
public void Test() 
{ 
    var _mongoServer = MongoServer.Create("mongodb://localhost:27020"); 
    var database = _mongoServer.GetDatabase("StackoverflowExamples"); 
    var col = database.GetCollection("items"); 

    //Add test data 
    col.Insert(new Item() { IntValue = 1, SomeOtherField = "Test" }); 
    col.Insert(new Item() { IntValue = 2 }); 
    col.Insert(new Item() { IntValue = 3 }); 
    col.Insert(new Item() { IntValue = 4 }); 

    var item = col.FindAs<Item>(Query.And()) 
    .SetSortOrder(SortBy.Ascending("IntValue")) 
    .SetLimit(1) 
    .SetFields("IntValue") //here i loading only field that i need 
    .Single(); 
    var minValue = item.IntValue; 

    //Check that we found min value of IntValue field 
    Assert.AreEqual(1, minValue); 
    //Check that other fields are null in the document 
    Assert.IsNull(item.SomeOtherField); 
    col.RemoveAll(); 
} 

而且Item類:

public class Item 
{ 
    public Item() 
    { 
    Id = ObjectId.GenerateNewId(); 
    } 

    [BsonId] 
    public ObjectId Id { get; set; } 
    public int IntValue { get; set; } 
    public string SomeOtherField { get; set; } 
} 

更新:總是試圖進一步移動,所以,這裏是集合中尋找最小值extention方法:

public static class MongodbExtentions 
{ 
    public static int FindMinValue(this MongoCollection collection, string fieldName) 
    { 
     var cursor = collection.FindAs<BsonDocument>(Query.And()) 
        .SetSortOrder(SortBy.Ascending(fieldName)) 
        .SetLimit(1) 
        .SetFields(fieldName); 

     var totalItemsCount = cursor.Count(); 

     if (totalItemsCount == 0) 
      throw new Exception("Collection is empty"); 

     var item = cursor.Single(); 

     if (!item.Contains(fieldName)) 
      throw new Exception(String.Format("Field '{0}' can't be find within '{1}' collection", fieldName, collection.Name)); 

     return item.GetValue(fieldName).AsInt32; // here we can also check for if it can be parsed 
    } 
} 

所以以上測試用例可以用這種擴展方法重寫:

[TestMethod] 
public void Test() 
{ 
    var _mongoServer = MongoServer.Create("mongodb://localhost:27020"); 
    var database = _mongoServer.GetDatabase("StackoverflowExamples"); 
    var col = database.GetCollection("items"); 

    var minValue = col.FindMinValue("IntValue"); 

    Assert.AreEqual(1, minValue); 
    col.RemoveAll(); 
} 

希望有人會使用它;)。

+0

謝謝!我正要爲c#驅動程序編寫代碼 – atbebtg 2011-06-15 17:03:57

+0

@atbebtg:不客氣。就在一秒之前,我已經更新了我的答案,所以我創建了用於查找最小值的擴展方法;) – 2011-06-15 17:06:32

+0

@Andred Orsich:哇!我不知道還有什麼要說的。再一次謝謝!不要擔心,我一定會使用該功能:) – atbebtg 2011-06-15 17:09:37

10

第一

db.sales.insert([ 
    { "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") }, 
    { "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") }, 
    { "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") }, 
    { "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") }, 
    { "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:05:00Z") } 
    ]) 

第二,找到最小值

db.sales.aggregate(
    [ 
    { 
     $group: 
     { 
     _id: {}, 
     minPrice: { $min: "$price" } 
     } 
    } 
    ] 
); 

結果是

{ "_id" : { }, "minPrice" : 5 } 

您還可以使用min函數這樣。

db.sales.aggregate(
    [ 
     { 
     $group: 
     { 
      _id: "$item", 
      minQuantity: { $min: "$quantity" } 
     } 
     } 
    ] 
) 

結果是

{ "_id" : "xyz", "minQuantity" : 5 } 
{ "_id" : "jkl", "minQuantity" : 1 } 
{ "_id" : "abc", "minQuantity" : 2 } 

$分鐘僅可在$組級的累加器運算符。

UPDATE: 改變在3.2版本:$分鐘是在$組和$項目階段提供。在之前的MongoDB版本中,$ min僅在$ group階段可用。

click here for more help

+1

錯誤:它可以在'$ project'階段使用。檢查您鏈接到的文檔。 – catalandres 2016-03-21 19:33:24