วิธีการเรียง 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

ฉันพบลิงค์อื่นที่บอกว่าฉันต้องวางคีย์ 'u' ไว้ด้านหน้าหากใช้ pymongo แต่ไม่ได้ผล ใครก็ตามที่ได้งานนี้หรือเป็นข้อผิดพลาด

คำตอบ:


302

.sort()ใน pymongo ใช้keyและdirectionเป็นพารามิเตอร์

ดังนั้นหากคุณต้องการเรียงลำดับสมมติว่า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/…
Shane Reustle

21
หมายเหตุ: จากน้อยไปมาก: 1, จากมากไปน้อย -1
Martlark

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

7

ทำไมหลามจึงใช้ list ของ tuples แทน dict

ในไพ ธ อนคุณไม่สามารถรับประกันได้ว่าพจนานุกรมจะถูกตีความตามลำดับที่คุณประกาศ

ดังนั้นใน mongo shell คุณสามารถทำได้.sort({'field1':1,'field2':1})และ interpreter ควรเรียง field1 ในระดับแรกและฟิลด์ 2 ในระดับที่สอง

หาก sintax นี้ถูกใช้ใน python มีโอกาสในการเรียงลำดับ field2 ในระดับแรก ด้วย tuple ไม่มีความเสี่ยง

.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:

  1. การใช้และ.find().sort()
  2. หรือใช้ไปป์ไลน์การรวม

ตามที่แนะนำโดย. find (). sort () เป็นวิธีที่ง่ายที่สุดในการเรียงลำดับ

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

อย่างไรก็ตามนี่เป็นกระบวนการที่ช้าเมื่อเทียบกับท่อรวม

มาถึงวิธีการรวมท่อ ขั้นตอนในการใช้ขั้นตอนการสรุปรวมแบบง่ายที่มีไว้สำหรับการเรียงลำดับคือ:

  1. $ จับคู่ (ขั้นตอนเพิ่มเติม)
  2. $ เรียงลำดับ

หมายเหตุ: จากประสบการณ์ของฉันขั้นตอนการรวมจะทำงานเร็วกว่า.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.