Come ordinare mongodb con pymongo


164

Sto cercando di utilizzare la funzione di ordinamento durante l'interrogazione del mio mongoDB, ma non riesce. La stessa query funziona nella console MongoDB ma non qui. Il codice è il seguente:

import pymongo

from  pymongo import Connection
connection = Connection()
db = connection.myDB
print db.posts.count()
for post in db.posts.find({}, {'entities.user_mentions.screen_name':1}).sort({u'entities.user_mentions.screen_name':1}):
    print post

L'errore che ottengo è il seguente:

Traceback (most recent call last):
  File "find_ow.py", line 7, in <module>
    for post in db.posts.find({}, {'entities.user_mentions.screen_name':1}).sort({'entities.user_mentions.screen_name':1},1):
  File "/Library/Python/2.6/site-packages/pymongo-2.0.1-py2.6-macosx-10.6-universal.egg/pymongo/cursor.py", line 430, in sort
  File "/Library/Python/2.6/site-packages/pymongo-2.0.1-py2.6-macosx-10.6-universal.egg/pymongo/helpers.py", line 67, in _index_document
TypeError: first item in each key pair must be a string

Ho trovato un link altrove che dice che devo usare un 'u' davanti alla chiave se uso pymongo, ma che non ha funzionato neanche. Chiunque altro riesce a farlo funzionare o è un bug.

Risposte:


302

.sort(), in pymongo, prende keye directioncome parametri.

Quindi, se vuoi ordinare per, diciamo, idallora dovresti.sort("_id", 1)

Per più campi:

.sort([("field1", pymongo.ASCENDING), ("field2", pymongo.DESCENDING)])

124
.sort([("field1",pymongo.ASCENDING), ("field2",pymongo.DESCENDING)])per ordinare più campi.
richardr,

4
Per chi cerca maggiori dettagli, ecco un link alla documentazione sull'ordinamento con pymongo api.mongodb.org/python/current/api/pymongo/…
Shane Reustle,

21
NOTA: crescente: 1, decrescente -1
Martlark

2
Qualche idea sul perché abbiano macellato la così semplice {"field1": 1, "field2": 1} notazione JSON?
Nico,

2
@Nico - vedi la risposta romulomadu sotto
Bajal

34

Puoi provare questo:

db.Account.find().sort("UserName")  
db.Account.find().sort("UserName",pymongo.ASCENDING)   
db.Account.find().sort("UserName",pymongo.DESCENDING)  

17

Questo funziona anche:

db.Account.find().sort('UserName', -1)
db.Account.find().sort('UserName', 1)

Sto usando questo nel mio codice, per favore commenta se sto facendo qualcosa di sbagliato qui, grazie.


Dovresti usare: ASCENDINGe DESCENDINGda pymongo. :)
Sn0pY,

7

Perché python utilizza invece l'elenco di tuple invece di dict?

In Python non è possibile garantire che il dizionario verrà interpretato nell'ordine dichiarato.

Quindi, nel guscio di mongo potresti farlo .sort({'field1':1,'field2':1}) e l'interprete dovrebbe ordinare field1 al primo livello e field 2 al secondo livello.

Se questa sintassi è stata utilizzata in Python, esiste la possibilità di ordinare field2 al primo livello. Con la tupla non c'è rischio.

.sort([("field1",pymongo.ASCENDING), ("field2",pymongo.DESCENDING)])

1
.sort([("field1",pymongo.ASCENDING), ("field2",pymongo.DESCENDING)])

Python usa chiave, direzione. Puoi usare il modo sopra.

Quindi nel tuo caso puoi farlo

for post in db.posts.find().sort('entities.user_mentions.screen_name',pymongo.ASCENDING):
        print post

0

TLDR: la pipeline di aggregazione è più veloce rispetto alla convenzionale .find().sort() .

Passiamo ora alla vera spiegazione. Esistono due modi per eseguire operazioni di ordinamento in MongoDB:

  1. Utilizzando .find()e.sort() .
  2. O usando la pipeline di aggregazione.

Come suggerito da molti .find (). Sort () è il modo più semplice per eseguire l'ordinamento.

.sort([("field1",pymongo.ASCENDING), ("field2",pymongo.DESCENDING)])

Tuttavia, questo è un processo lento rispetto alla pipeline di aggregazione.

Venendo al metodo della pipeline di aggregazione. I passaggi per implementare una pipeline di aggregazione semplice destinata all'ordinamento sono:

  1. $ match (passaggio facoltativo)
  2. $ sort

NOTA: nella mia esperienza, la pipeline di aggregazione funziona un po 'più velocemente di .find().sort() metodo.

Ecco un esempio della pipeline di aggregazione.

db.collection_name.aggregate([{
    "$match": {
        # your query - optional step
    }
},
{
    "$sort": {
        "field_1": pymongo.ASCENDING,
        "field_2": pymongo.DESCENDING,
        ....
    }
}])

Prova tu stesso questo metodo, confronta la velocità e fammi sapere nei commenti.

Modifica: non dimenticare di utilizzare allowDiskUse=Truedurante l'ordinamento su più campi, altrimenti genererà un errore.


0

Dì, vuoi ordinare per campo "Created_on", quindi puoi fare così,

.sort('{}'.format('created_on'), 1 if sort_type == 'asc' else -1)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.