如何在mongodb中找到最小值

Posted

技术标签:

【中文标题】如何在mongodb中找到最小值【英文标题】:How to find min value in mongodb 【发布时间】:2011-06-15 15:43:32 【问题描述】:

你是怎么做到的

SELECT 
  MIN(Id) AS MinId
FROM
  Table

使用 MongoDB?

看起来我必须使用 MapReduce,但我找不到任何示例来说明如何做到这一点。

【问题讨论】:

【参考方案1】:

您可以使用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 shell 中编写的,但您可以使用 C# 或任何其他语言使用适当的驱动程序方法来执行相同的操作。

【讨论】:

注意:对于任何大型数据集,您可能需要在 a: 1 上建立索引。 这仍然是获得最小值的最佳方式吗? 您现在可以使用聚合框架来实现此结果。请参阅以下来自wanghao的答案。 db.myCollection.aggregate( [ $group: _id: , minPrice: $min: "$price" ] );【参考方案2】:

第一个

  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 

$min 是一个累加器运算符,仅在 $group 阶段可用。

更新: 在 3.2 版更改: $min 在 $group 和 $project 阶段可用。在以前的 MongoDB 版本中,$min 仅在 $group 阶段可用。

click here for more help

【讨论】:

False:可以在$project阶段使用。检查您链接到的文档。 这比接受的答案慢得多。 如果特定字段被索引,.find().sort(query) 将几乎是即时的。【参考方案3】:

只是想展示如何使用官方 c# 驱动程序(因为关于 mongodb csharp 的问题)进行一项改进:我只加载一个字段,但如果我只想找到该字段的最小值,则不是整个文档。这是完整的测试用例:

[TestMethod]
public void Test()

  var _mongoServer = MongoServer.Create("mongodb://localhost:27020");
  var database = _mongoServer.GetDatabase("***Examples");
  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; 

更新:总是试图进一步移动,所以,这里是在集合中找到最小值的扩展方法:

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("***Examples");
  var col = database.GetCollection("items");

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

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

希望有人会使用它;)。

【讨论】:

谢谢!我正要写c#驱动的代码 @atbebtg:不客气。就在一秒钟前,我更新了我的答案,所以我创建了扩展方法来查找最小值;) @Andred Orsich:哇!我不知道还能说什么。再次感谢您!别担心,我一定会用那个功能的:)

以上是关于如何在mongodb中找到最小值的主要内容,如果未能解决你的问题,请参考以下文章

如何在地图中找到最小值?

如何在numpy矩阵中找到最小值?

如何在带有边界的python优化中找到全局最小值?

如何在有界的python优化中找到全局最小值?

如何在opencv中找到图像的最大和最小亮度值?

如何在excel中找到多个最小值而不重复?