Suppongo che tu abbia i seguenti documenti nella vostra collezione.
{ "_id" : ObjectId("56801243fb940e32f3221bc2"), "a" : 0 }
{ "_id" : ObjectId("56801243fb940e32f3221bc3"), "a" : 1 }
{ "_id" : ObjectId("56801243fb940e32f3221bc4"), "a" : 2 }
{ "_id" : ObjectId("56801243fb940e32f3221bc5"), "a" : 3 }
{ "_id" : ObjectId("56801243fb940e32f3221bc6"), "a" : 4 }
{ "_id" : ObjectId("56801243fb940e32f3221bc7"), "a" : 5 }
{ "_id" : ObjectId("56801243fb940e32f3221bc8"), "a" : 6 }
{ "_id" : ObjectId("56801243fb940e32f3221bc9"), "a" : 7 }
Da MongoDB 3.2 è possibile utilizzare il metodo .aggregate()
e l'operatore $slice
.
db.collection.aggregate([
{ "$group": {
"_id": null,
"count": { "$sum": 1 },
"docs": { "$push": "$$ROOT" }
}},
{ "$project": {
"count": 1,
"_id": 0,
"docs": { "$slice": [ "$docs", 2, 3 ] }
}}
])
che restituisce:
{
"count" : 8,
"docs" : [
{
"_id" : ObjectId("56801243fb940e32f3221bc4"),
"a" : 2
},
{
"_id" : ObjectId("56801243fb940e32f3221bc5"),
"a" : 3
},
{
"_id" : ObjectId("56801243fb940e32f3221bc6"),
"a" : 4
}
]
}
Si consiglia di ordinare il documento prima di raggruppamento utilizzando l'operatore $sort
.
Da MongoDB 3.0 all'indietro dovrai primi $group
i documenti e utilizzare l'operatore $sum
dell'accumulatore di restituire il "conteggio" dei documenti; anche nella stessa fase di gruppo è necessario utilizzare la variabile $push
e la variabile $$ROOT
per restituire un array di tutti i tuoi documenti. La fase successiva della pipeline sarà quindi la fase $unwind
in cui denormalizzare quella matrice. Da lì utilizzare gli operatori $skip
e $limit
rispettivamente saltare i primi 2 documenti e passare 3 documenti allo stage successivo che è un altro stage $group
.
db.collection.aggregate([
{ "$group": {
"_id": null,
"count": { "$sum": 1 },
"docs": { "$push": "$$ROOT" }
}},
{ "$unwind": "$docs" },
{ "$skip": 2 },
{ "$limit": 3 },
{ "$group": {
"_id": "$_id",
"count": { "$first": "$count" },
"docs": { "$push": "$docs" }
}}
])
Come @JohnnyHK ha sottolineato in questo comment
$group
sta per leggere tutti i documenti e di costruire una serie di elementi 20k con loro solo per avere tre documenti.
Si dovrebbe quindi eseguire due query utilizzando find()
db.collection.find().skip(2).limit(3)
e
db.collection.count()
Buone idee, ma che '$ group' leggerà tutti i documenti e costruirà un array di elementi 20k con loro solo per ottenere tre documenti. Difficile credere che questo sarebbe più efficiente di due domande. – JohnnyHK