如何在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】:您可以使用sort
和limit
的组合来模拟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中找到最小值的主要内容,如果未能解决你的问题,请参考以下文章