Cách sắp xếp mongodb với pymongo


164

Tôi đang cố gắng sử dụng tính năng sắp xếp khi truy vấn mongoDB của mình, nhưng nó không thành công. Truy vấn tương tự hoạt động trong bảng điều khiển MongoDB nhưng không phải ở đây. Mã như sau:

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

Lỗi tôi nhận được như sau:

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

Tôi đã tìm thấy một liên kết ở nơi khác nói rằng tôi cần đặt một chữ 'u' trước phím nếu sử dụng pymongo, nhưng nó cũng không hoạt động. Bất cứ ai khác có được điều này để làm việc hoặc đây là một lỗi.

Câu trả lời:


302

.sort(), trong pymongo, mất keydirection làm tham số.

Vì vậy, nếu bạn muốn sắp xếp theo, giả sử, idbạn nên.sort("_id", 1)

Đối với nhiều lĩnh vực:

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

124
.sort([("field1",pymongo.ASCENDING), ("field2",pymongo.DESCENDING)])để sắp xếp nhiều lĩnh vực.
richardr

4
Đối với những người tìm kiếm thêm chi tiết, đây là một liên kết đến tài liệu sắp xếp với pymongo api.mongodb.org/python/cien/api/pymongo/ (
Shane Reustle 21/1/2015

21
LƯU Ý: tăng dần: 1, giảm dần -1
Martlark

2
Có ai biết tại sao họ lại đánh dấu {"field1": 1, "field2": 1} ký hiệu JSON dễ dàng như vậy không?
Nico

2
@Nico - xem câu trả lời romulomadu dưới đây
Bajal

34

Bạn có thể thử điều này:

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

17

Điều này cũng hoạt động:

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

Tôi đang sử dụng mã này trong mã của mình, vui lòng nhận xét nếu tôi đang làm gì đó sai ở đây, cảm ơn.


Bạn nên sử dụng: ASCENDINGDESCENDINGtừ pymongo. :)
Sn0pY

7

Tại sao python sử dụng danh sách các bộ dữ liệu thay vì dict?

Trong python bạn không thể đảm bảo rằng từ điển sẽ được diễn giải theo thứ tự bạn đã khai báo.

Vì vậy, trong mongo shell bạn có thể làm .sort({'field1':1,'field2':1})và trình thông dịch nên sắp xếp trường1 ở cấp đầu tiên và trường 2 ở cấp thứ hai.

Nếu sintax này được sử dụng trong python, có cơ hội sắp xếp field2 ở cấp độ đầu tiên. Với tuple không có rủi ro.

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

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

Python dùng khóa, hướng. Bạn có thể sử dụng cách trên.

Vì vậy, trong trường hợp của bạn, bạn có thể làm điều này

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

0

TLDR: Đường ống tổng hợp nhanh hơn so với thông thường .find().sort().

Bây giờ chuyển sang giải thích thực sự. Có hai cách để thực hiện các hoạt động sắp xếp trong MongoDB:

  1. Sử dụng .find().sort().
  2. Hoặc sử dụng đường ống tổng hợp.

Theo đề xuất của nhiều .find (). Sort () là cách đơn giản nhất để thực hiện sắp xếp.

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

Tuy nhiên, đây là một quá trình chậm so với đường ống tổng hợp.

Đến với phương pháp đường ống tổng hợp. Các bước để thực hiện đường ống tổng hợp đơn giản dành cho sắp xếp là:

  1. $ khớp (bước tùy chọn)
  2. $ sắp xếp

LƯU Ý: Theo kinh nghiệm của tôi, đường ống tổng hợp hoạt động nhanh hơn một chút so với .find().sort()phương pháp.

Đây là một ví dụ về đường ống tổng hợp.

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

Hãy tự thử phương pháp này, so sánh tốc độ và cho tôi biết về điều này trong các bình luận.

Chỉnh sửa: Đừng quên sử dụng allowDiskUse=Truetrong khi sắp xếp trên nhiều trường nếu không nó sẽ gây ra lỗi.


0

Giả sử, bạn muốn sắp xếp theo trường 'created_on', sau đó bạn có thể làm như thế này,

.sort('{}'.format('created_on'), 1 if sort_type == 'asc' else -1)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.