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.

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)])

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)  

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.


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)])

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

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.


0

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

.sort('{}'.format('created_on'), 1 if sort_type == 'asc' else -1)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.