Mongodb'u pymongo ile sıralama


164

Benim mongoDB sorgulama sırasında sıralama özelliğini kullanmaya çalışıyorum, ama başarısız. Aynı sorgu MongoDB konsolunda çalışır, ancak burada çalışmaz. Kod aşağıdaki gibidir:

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

Aldığım hata aşağıdaki gibidir:

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

Başka bir yerde, pymongo kullanıyorsanız, anahtarın önüne "u" koymam gerektiğini söyleyen bir bağlantı buldum, ancak bu da işe yaramadı. Herkes bu işe olsun ya da bu bir hata.

Yanıtlar:


302

.sort(), pymongo'da keyve directionparametre olarak alır .

Sıralama ölçütü olarak kullanmak istiyorsanız, en, diyelim ido zaman gerekir.sort("_id", 1)

Birden çok alan için:

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

124
.sort([("field1",pymongo.ASCENDING), ("field2",pymongo.DESCENDING)])birden çok alanı sıralamak için.
richardr

4
Daha fazla ayrıntı için arayanlar için buraya pymongo ile sıralama üzerinde belgelerine bir bağlantı api.mongodb.org/python/current/api/pymongo/...
Shane Reustle

21
NOT: artan: 1, azalan -1
Martlark

2
Neden bu kadar kolay {"field1": 1, "field2": 1} JSON gösterimini değiştirdiler?
Nico

2
@Nico - aşağıdaki romulomadu cevabına bakın
Bajal

34

Bunu deneyebilirsiniz:

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

17

Bu ayrıca işe yarar:

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

Kodumda bu kullanıyorum, burada yanlış bir şey yapıyorsanız lütfen yorum, teşekkürler.


Sen kullanmalıdır: ASCENDINGve DESCENDINGgelen pymongo. :)
Sn0pY

7

Neden python dikte yerine tuples listesini kullanıyor?

Python'da sözlüğün bildirdiğiniz sırada yorumlanacağını garanti edemezsiniz.

Yani, mongo kabuğunda yapabilirsiniz .sort({'field1':1,'field2':1})ve yorumlayıcı birinci seviyede alan1 ve ikinci seviyede alan 2 sıralamalıdır.

Bu sintaks python'da kullanılmışsa, field2'yi birinci seviyede sıralama şansı vardır. Tuple ile risk yoktur.

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

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

Python anahtar, yön kullanır. Yukarıdaki yolu kullanabilirsiniz.

Yani sizin durumunuzda bunu yapabilirsiniz

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

0

TLDR: Toplama boru hattı geleneksel yöntemlere göre daha hızlıdır .find().sort().

Şimdi gerçek açıklamaya geçiyorum. MongoDB'de sıralama işlemleri yapmanın iki yolu vardır:

  1. Kullanılması .find()ve .sort().
  2. Veya toplama boru hattını kullanarak.

Birçok .find (). Sort () tarafından önerildiği gibi, sıralama yapmanın en basit yoludur.

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

Bununla birlikte, bu, toplama boru hattına kıyasla yavaş bir işlemdir.

Toplama boru hattı yöntemine geliyor. Sıralama amaçlı basit toplama boru hattını uygulama adımları:

  1. $ match (isteğe bağlı adım)
  2. $ sıralama

NOT: Deneyimlerime göre, toplama boru hattı .find().sort()yöntemden biraz daha hızlı çalışır .

Toplama boru hattına bir örnek.

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

Bu yöntemi kendiniz deneyin, hızı karşılaştırın ve yorumlarda bunu bana bildirin.

Düzenleme: allowDiskUse=TrueBirden fazla alanda sıralama yaparken kullanmayı unutmayın, aksi takdirde bir hata atar.


0

Diyelim ki, 'created_on' alanına göre sıralamak istiyorsunuz, o zaman bunu yapabilirsiniz,

.sort('{}'.format('created_on'), 1 if sort_type == 'asc' else -1)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.