Wie man Mongodb mit Pymongo sortiert

164

Ich versuche, die Sortierfunktion zu verwenden, wenn ich meine mongoDB abfrage, aber sie schlägt fehl. Die gleiche Abfrage funktioniert in der MongoDB-Konsole, jedoch nicht hier. Der Code lautet wie folgt:

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

Der Fehler, den ich bekomme, ist wie folgt:

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

Ich habe an anderer Stelle einen Link gefunden, der besagt, dass ich bei Verwendung von Pymongo ein 'u' vor den Schlüssel setzen muss, aber das hat auch nicht funktioniert. Jeder andere bringt das zum Laufen oder ist das ein Fehler?

WildBill
quelle

Antworten:

302

.sort()nimmt im Pymongo keyund directionals Parameter.

Wenn Sie also sortieren möchten, sagen wir, iddann sollten Sie.sort("_id", 1)

Für mehrere Felder:

.sort([("field1", pymongo.ASCENDING), ("field2", pymongo.DESCENDING)])
Ben
quelle
124
.sort([("field1",pymongo.ASCENDING), ("field2",pymongo.DESCENDING)])um mehrere Felder zu sortieren.
Richard
4
Für diejenigen, die nach weiteren Details suchen, ist hier ein Link zur Dokumentation zum Sortieren mit pymongo api.mongodb.org/python/current/api/pymongo/…
Shane Reustle
21
HINWEIS: aufsteigend: 1, absteigend -1
Martlark
2
Irgendeine Idee, warum sie die so einfache JSON-Notation {"field1": 1, "field2": 1} abgeschlachtet haben?
Nico
2
@ Nico - siehe Romulomadu Antwort unten
Bajal
34

Sie können dies versuchen:

db.Account.find().sort("UserName")  
db.Account.find().sort("UserName",pymongo.ASCENDING)   
db.Account.find().sort("UserName",pymongo.DESCENDING)  
neues Licht
quelle
17

Das funktioniert auch:

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

Ich verwende dies in meinem Code. Bitte kommentieren Sie, wenn ich hier etwas falsch mache. Danke.

Snehal Parmar
quelle
Sie sollten verwenden: ASCENDINGund DESCENDINGvon pymongo. :)
Sn0pY
7

Warum verwendet Python stattdessen eine Liste von Tupeln?

In Python können Sie nicht garantieren, dass das Wörterbuch in der von Ihnen angegebenen Reihenfolge interpretiert wird.

In der Mongo-Shell könnten Sie dies tun, .sort({'field1':1,'field2':1})und der Interpreter sollte Feld 1 auf der ersten Ebene und Feld 2 auf der zweiten Ebene sortieren.

Wenn diese Sintax in Python verwendet wurde, besteht die Möglichkeit, Feld2 auf der ersten Ebene zu sortieren. Mit Tupel besteht kein Risiko.

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

Python verwendet Schlüssel, Richtung. Sie können den obigen Weg verwenden.

In Ihrem Fall können Sie dies also tun

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

TLDR: Die Aggregationspipeline ist im Vergleich zu herkömmlichen Pipelines schneller .find().sort().

Kommen wir nun zur eigentlichen Erklärung. Es gibt zwei Möglichkeiten, Sortiervorgänge in MongoDB auszuführen:

  1. Verwenden von .find()und .sort().
  2. Oder mithilfe der Aggregationspipeline.

Wie von vielen vorgeschlagen .Find (). Sort () ist der einfachste Weg, um die Sortierung durchzuführen.

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

Dies ist jedoch im Vergleich zur Aggregationspipeline ein langsamer Prozess.

Kommen wir zur Aggregationspipeline-Methode. Die Schritte zum Implementieren einer einfachen Aggregationspipeline zum Sortieren sind:

  1. $ match (optionaler Schritt)
  2. $ sort

HINWEIS: Nach meiner Erfahrung arbeitet die Aggregationspipeline etwas schneller als die .find().sort()Methode.

Hier ist ein Beispiel für die Aggregationspipeline.

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

Probieren Sie diese Methode selbst aus, vergleichen Sie die Geschwindigkeit und teilen Sie mir dies in den Kommentaren mit.

Bearbeiten: Vergessen Sie nicht, allowDiskUse=Truebeim Sortieren nach mehreren Feldern zu verwenden, da sonst ein Fehler auftritt.

Anuj Gupta
quelle
0

Angenommen, Sie möchten nach dem Feld 'created_on' sortieren, dann können Sie dies folgendermaßen tun:

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