Come si fa a fare l'equivalente diCome trovare valore minimo in MongoDB
SELECT
MIN(Id) AS MinId
FROM
Table
in MongoDB. Sembra che dovrò usare MapReduce ma non riesco a trovare alcun esempio che mostri come farlo.
Grazie.
Come si fa a fare l'equivalente diCome trovare valore minimo in MongoDB
SELECT
MIN(Id) AS MinId
FROM
Table
in MongoDB. Sembra che dovrò usare MapReduce ma non riesco a trovare alcun esempio che mostri come farlo.
Grazie.
È possibile utilizzare una combinazione di sort
e limit
per emulare 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})
è un ordine crescente (minimo-prima) sul campo a
, e poi restituire solo il primo documento, che sarà essere il valore minimo per quel campo
MODIFICA: nota che questo è scritto nella shell mongo, ma puoi fare la stessa cosa da C# o qualsiasi altra lingua usando i metodi appropriati del driver.
Voglio solo mostrare come può essere fatto con il driver C# ufficiale (da una domanda su mongodb csharp) con un miglioramento: sto caricando solo un campo, ma non tutto il documento se voglio solo trovare il valore Min di quel campo. Qui è completo banco di prova:
[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();
}
E Item
classe:
public class Item
{
public Item()
{
Id = ObjectId.GenerateNewId();
}
[BsonId]
public ObjectId Id { get; set; }
public int IntValue { get; set; }
public string SomeOtherField { get; set; }
}
Aggiornamento: sempre cercando di avvicinarsi ulteriormente, così, qui è il metodo estensione per la ricerca di valore minimo all'interno della collezione:
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
}
}
Così sopra il caso di test con questo metodo di estensione può essere riscritto in questo modo:
[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();
}
Spero che qualcuno lo userà;).
Grazie! Stavo per scrivere il codice per il driver C# – atbebtg
@atbebtg: sei il benvenuto. Solo un secondo fa ho aggiornato la mia risposta, quindi ho creato il metodo di estensione per trovare il valore minimo;) –
@Andred Orsich: Wow! Non so cos'altro dire. Ancora una volta grazie! Non preoccuparti, userò sicuramente quella funzione :) – atbebtg
Il primo
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") }
])
Il secondo, trovare il valore minimo
db.sales.aggregate(
[
{
$group:
{
_id: {},
minPrice: { $min: "$price" }
}
}
]
);
risultato è
{ "_id" : { }, "minPrice" : 5 }
È inoltre possibile utilizzare la funzione min come questo.
db.sales.aggregate(
[
{
$group:
{
_id: "$item",
minQuantity: { $min: "$quantity" }
}
}
]
)
risultato sono
{ "_id" : "xyz", "minQuantity" : 5 }
{ "_id" : "jkl", "minQuantity" : 1 }
{ "_id" : "abc", "minQuantity" : 2 }
$ min è un operatore di accumulo disponibile solo nella fase $ gruppo.
UPDATE: Modificato nella versione 3.2: $ min è disponibile nelle fasi $ gruppo e $ di progetto. Nelle versioni precedenti di MongoDB, $ min è disponibile solo nella fase $ gruppo.
Falso: può essere utilizzato nella fase '$ project'. Controlla il documento a cui ti colleghi. – catalandres
Nota: probabilmente si vorrà un indice su un {1} per ogni grande insieme di dati. –
è ancora il modo ottimale per ottenere un valore minimo? – clifgray
Ora è possibile utilizzare il framework Aggregate per ottenere questo risultato. Vedi la risposta qui sotto da wanghao. db.myCollection.aggregate ( [ { $ gruppo: { _id: {}, MINPRICE: {$ min: "$ prezzo"}} } ] ); – Waqas