Comment trouver la valeur min en mongodb
Comment faire l'équivalent de
SELECT
MIN(Id) AS MinId
FROM
Table
en MongoDB. Il semble que je vais devoir utiliser MapReduce mais je ne trouve aucun exemple qui montrent comment faire cela.
je vous Remercie.
3 réponses
Vous pouvez utiliser une combinaison de sort
et limit
pour émuler 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})
est un Tri ascendant (minimum-premier) sur le a
champ, et ensuite nous retourner uniquement le premier document, qui sera la valeur minimale pour ce champ.
EDIT: notez que ceci est écrit dans le shell mongo, mais vous pouvez faire la même chose depuis C# ou tout autre langage en utilisant les méthodes de pilote appropriées.
Le premier
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") }
])
la seconde, trouver la valeur min
db.sales.aggregate(
[
{
$group:
{
_id: {},
minPrice: { $min: "$price" }
}
}
]
);
le résultat est
{ "_id" : { }, "minPrice" : 5 }
vous pouvez aussi utiliser la fonction min comme celle-ci.
db.sales.aggregate(
[
{
$group:
{
_id: "$item",
minQuantity: { $min: "$quantity" }
}
}
]
)
résultat
{ "_id" : "xyz", "minQuantity" : 5 }
{ "_id" : "jkl", "minQuantity" : 1 }
{ "_id" : "abc", "minQuantity" : 2 }
$ min est un opérateur d'accumulateur disponible seulement dans l'étape $group.
mise à jour: Modifié dans la version 3.2: $min est disponible dans les étapes $group et $project. Dans les versions précédentes de MongoDB, $min is disponible dans l' $en phase de groupe seulement.
je veux juste montrer comment cela peut être fait avec le pilote officiel c# (depuis la question sur mongodb csharp) avec une amélioration: je charge seulement un champ, mais pas le document entier si je veux juste trouver la valeur Min de ce champ. Voici le cas de test complet:
[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();
}
Et Item
catégorie :
public class Item
{
public Item()
{
Id = ObjectId.GenerateNewId();
}
[BsonId]
public ObjectId Id { get; set; }
public int IntValue { get; set; }
public string SomeOtherField { get; set; }
}
mise à Jour: toujours essayer d'aller plus loin, donc, voici la méthode d'extension pour trouver la valeur min dans la collection:
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
}
}
Si le test ci-dessus case avec cette méthode d'extension peut être rewrité comme ceci:
[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();
}
j'Espère que quelqu'un va l'utiliser ;).