2015-12-27 7 views
5

Ho 20.000 documenti in my mongodb. Ho appena saputo che non puoi interrogarli tutti in una volta.Risultato query limitante in MongoDB

Quindi la mia domanda è questa:

voglio avere il mio documento utilizzando find(query) quindi limitare i suoi risultati solo per 3 documenti e posso scegliere dove tali documenti partono da.

Per esempio, se la mia domanda find() ha provocato 8 documenti:

[{doc1}, {doc2}, {doc3}, {doc4}, {doc5}, {doc6}, {doc7}, {doc 8}] 

comando limit(2, 3) volontà dà [doc3, doc4, doc5]

E ho anche bisogno di ottenere conteggio totale per tutto ciò che risultato (senza limiti), per esempio: length() darà 8 (il numero del documento totale risultante dalla funzione find())

Qualche suggerimento? Grazie

risposta

4

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() 
+3

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

7

aggiungere .skip(2).limit(3) alla fine della query

+0

Ah, la ringrazio per questa risposta rapida. Quindi come ottengo il risultato totale? Voglio dire, voglio sapere quanti moduli di conteggio trovare() senza interrogare lo stesso parametro di ricerca due volte? – DennyHiu

+0

Non sono sicuro di cosa intendi. vuoi contare quanti risultati hai ottenuto limitando il risultato impostato a 3? –

+0

No, costruisco un datatable (jquery datatable) e richiede qualcosa come - var total = db.transaction.find(). Length; e var data = db.transaction.find(). skip (2) .limit (3). TOTAL e DATA sono cose diverse – DennyHiu