mongodbをpymongoでソートする方法


164

mongoDBにクエリを実行するときに並べ替え機能を使用しようとしていますが、失敗します。同じクエリがMongoDBコンソールで機能しますが、ここでは機能しません。コードは次のとおりです。

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

私が得るエラーは次のとおりです:

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

pymongoを使用する場合、キーの前に「u」を配置する必要があるという他のリンクを見つけましたが、それも機能しませんでした。他の誰かがこれを機能させるか、これはバグです。

回答:


302

.sort()、pymongoでは、パラメータとしてkeydirectionを取ります。

したがって、並べ替えidを行う場合は、たとえば、.sort("_id", 1)

複数のフィールドの場合:

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

124
.sort([("field1",pymongo.ASCENDING), ("field2",pymongo.DESCENDING)])複数のフィールドをソートします。
richardr

4
詳細をお探しの方は、こちらpymongoのでソート上のドキュメントへのリンクですapi.mongodb.org/python/current/api/pymongo/...は
シェーンReustle

21
注:昇順:1、降順-1
Martlark、2015

2
彼らがなぜそんなに簡単な{"field1":1、 "field2":1} JSON表記を屠殺したのか?
Nico

2
@Nicoは-の下romulomadu答えを見る
Bajal

34

あなたはこれを試すことができます:

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

17

これも機能します:

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

私はコードでこれを使用しています。ここで何か間違っている場合はコメントしてください、ありがとうございます。


次を使用する必要があります:ASCENDINGおよびDESCENDINGからpymongo。:)
Sn0pY 2018年

7

なぜpythonがdictではなくタプルのリストを使用するのですか?

Pythonでは、宣言した順序で辞書が解釈されることは保証できません。

したがって、mongoシェルではこれを行うことができ.sort({'field1':1,'field2':1})、インタープリターはfield1を第1レベルで、field 2を第2レベルでソートする必要があります。

この構文がPythonで使用された場合、field2を最初のレベルでソートする機会があります。タプルがあればリスクはありません。

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

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

Pythonはキーと方向を使用します。上記の方法を使用できます。

あなたの場合、あなたはこれを行うことができます

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

0

TLDR:集約パイプラインは、従来のと比較して高速.find().sort()です。

実際の説明に移ります。MongoDBでソート操作を実行するには、2つの方法があります。

  1. とを使用.find().sort()ます。
  2. または、集計パイプラインを使用します。

多くの.find()。sort()が示唆しているように、ソートを実行する最も簡単な方法です。

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

ただし、これは集約パイプラインと比較して遅いプロセスです。

集約パイプライン方式になりました。並べ替えを目的とした単純な集計パイプラインを実装する手順は次のとおりです。

  1. $ match(オプションのステップ)
  2. $ sort

注:私の経験では、集約パイプラインは.find().sort()メソッドよりも少し速く機能します。

以下は、集約パイプラインの例です。

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

この方法を自分で試し、速度を比較して、コメントでこのことを知らせてください。

編集:allowDiskUse=True複数のフィールドでソートするときに使用することを忘れないでください。そうしないと、エラーがスローされます。


0

たとえば、「created_on」フィールドで並べ替えるには、次のようにします。

.sort('{}'.format('created_on'), 1 if sort_type == 'asc' else -1)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.