Cómo ordenar mongodb con pymongo

164

Estoy tratando de usar la función de clasificación al consultar mi mongoDB, pero está fallando. La misma consulta funciona en la consola MongoDB pero no aquí. El código es el siguiente:

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

El error que obtengo es el siguiente:

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

Encontré un enlace en otro lugar que dice que necesito colocar una 'u' delante de la clave si utilizo pymongo, pero tampoco funcionó. Alguien más consigue que esto funcione o es un error.

WildBill
fuente

Respuestas:

302

.sort(), en pymongo, toma keyydirection como parámetros.

Entonces, si quieres ordenar, digamos, identonces deberías.sort("_id", 1)

Para múltiples campos:

.sort([("field1", pymongo.ASCENDING), ("field2", pymongo.DESCENDING)])
Ben
fuente
124
.sort([("field1",pymongo.ASCENDING), ("field2",pymongo.DESCENDING)])para ordenar múltiples campos.
richardr
44
Para aquellos que buscan más detalles, aquí hay un enlace a la documentación sobre la clasificación con pymongo api.mongodb.org/python/current/api/pymongo/…
Shane Reustle
21
NOTA: ascendente: 1, descendente -1
Martlark
2
¿Alguna idea de por qué mataron la notación JSON tan fácil {"field1": 1, "field2": 1}?
Nico
2
@Nico - vea la respuesta de romulomadu a continuación
Bajal
34

Puedes probar esto:

db.Account.find().sort("UserName")  
db.Account.find().sort("UserName",pymongo.ASCENDING)   
db.Account.find().sort("UserName",pymongo.DESCENDING)  
nueva luz
fuente
17

Esto también funciona:

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

Estoy usando esto en mi código, por favor comente si estoy haciendo algo mal aquí, gracias.

Snehal Parmar
fuente
Debe usar: ASCENDINGy DESCENDINGde pymongo. :)
Sn0pY
7

¿Por qué Python usa la lista de tuplas en lugar de dict?

En python no puede garantizar que el diccionario se interpretará en el orden que declaró.

Entonces, en mongo shell podrías hacer .sort({'field1':1,'field2':1})y el intérprete debería ordenar el campo 1 en el primer nivel y el campo 2 en el segundo nivel.

Si esta sintaxis se usó en python, existe la posibilidad de ordenar field2 en el primer nivel. Con la tupla no hay riesgo.

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

Python usa clave, dirección. Puedes usar la forma anterior.

Entonces en tu caso puedes hacer esto

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

TLDR: la canalización de agregación es más rápida en comparación con la convencional .find().sort().

Ahora pasando a la explicación real. Hay dos formas de realizar operaciones de clasificación en MongoDB:

  1. Usando .find()y .sort().
  2. O usando la tubería de agregación.

Como lo sugieren muchos .find (). Sort () es la forma más sencilla de realizar la ordenación.

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

Sin embargo, este es un proceso lento en comparación con la canalización de agregación.

Llegando al método de canalización de agregación. Los pasos para implementar una tubería de agregación simple destinada a la clasificación son:

  1. $ partido (paso opcional)
  2. $ sort

NOTA: En mi experiencia, la canalización de agregación funciona un poco más rápido que el .find().sort()método.

Aquí hay un ejemplo de la tubería de agregación.

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

Pruebe este método usted mismo, compare la velocidad y hágamelo saber en los comentarios.

Editar: no olvide usarlo allowDiskUse=Truemientras ordena en varios campos, de lo contrario arrojará un error.

Anuj Gupta
fuente
0

Digamos que desea ordenar por campo 'created_on', luego puede hacer esto,

.sort('{}'.format('created_on'), 1 if sort_type == 'asc' else -1)
MD Tanvir Raihan
fuente