2014-04-10 11 views
12

Tôi đang cố gắng lấy từ điển đặt hàng ở Pymongo. Tôi đã đọc nó có thể được thực hiện với bson.son.Son. Tài liệu là HereLàm thế nào để có được các bộ từ điển theo thứ tự trong pymongo?

Tuy nhiên, tôi dường như không làm cho nó hoạt động. Không có nhiều trên google về nó. Có một số cuộc thảo luận về cấu hình pymongo đầu tiên để nói với nó để sử dụng các đối tượng SON nhưng không có ví dụ. Một người bạn đã đề xuất chuyển thông số khi bạn thực hiện tìm kiếm. Anh không thể nhớ.

Tôi có thể tạo đối tượng SON. Nhưng khi họ được đưa vào DB và sau đó quay trở lại ra ngoài họ chỉ là đồng bằng dicts.

Tôi không chắc chắn thực sự là ví dụ mã để cung cấp cho bạn vì tôi thực sự không biết bắt đầu từ đâu. Đoạn mã dưới đây tạo đối tượng SON trống mỗi lần tôi thêm người dùng mới. Đối tượng 'sub_users' cũng được tạo bằng SON. Khi tôi đọc tài liệu tài khoản trở lại từ DB họ chỉ là con trăn bình thường.

account['sub_users'][sub_user_name] = bson.SON() 
    with mongo_manager.Collection(CFG.db, 'Users') as users: 
     users.save(account) 

Có thể thông qua quá trình tìm kiếm như thế này để định cấu hình? Đây là đề nghị bạn bè của tôi nhưng anh không thể nhớ.

with mongo_manager.Collection(CFG.db, 'Users') as users:         
    account = users.find_one({'_id': _id, 'DOC':'OrderedDict}) 

Bất kỳ ý tưởng nào?

Trả lời

9

Bạn có thể sử dụng bson.son.SON hoặc OrderedDict để lưu trữ lệnh bắt buộc.

Và truy xuất dữ liệu với tùy chọn as_class=OrderedDict.

Dưới đây là một ví dụ:

from collections import OrderedDict 
from pymongo import MongoClient 
import bson 

client = MongoClient() 
sample_db = client['sample'] 
test_col = sample_db['test'] 

test_col.drop() 

data = OrderedDict([("one", 1), ("two", 2), ("three", 3), ("four", 4)]) 
test_col.insert(data) 
print(list(test_col.find({}, {'_id': 0}, as_class=OrderedDict))) 

test_col.drop() 

data = bson.son.SON([("one", 1), ("two", 2), ("three", 3), ("four", 4)]) 
test_col.insert(data) 
print(list(test_col.find({}, {'_id': 0}, as_class=OrderedDict))) 

Output:

[OrderedDict([(u'one', 1), (u'two', 2), (u'three', 3), (u'four', 4)])] 
[OrderedDict([(u'one', 1), (u'two', 2), (u'three', 3), (u'four', 4)])] 
+0

Câu trả lời thú vị. cảm ơn. –

+0

+1 thông minh và hữu ích – shx2

+1

Có sự khác biệt nào về hiệu suất giữa việc sử dụng đối tượng 'OrderedDict' và' SON' không? Nhìn vào các nguồn ([ở đây] (https://github.com/mongodb/mongo-python-driver/blob/master/bson/son.py#L33), và [ở đây] (https://github.com /python/cpython/blob/d4edfc9abffca965e76ebc5957a92031a4d6c4d4/Lib/collections/__init__.py)), cả hai đều là các lớp con của 'dict', nhưng' OrderedDict' có triển khai C (với một Python thuần túy là dự phòng) trong khi 'SON' có vẻ để chỉ thực hiện Python ... –

13

Giải pháp này trên là chính xác cho các phiên bản cũ của MongoDB và người lái xe pymongo nhưng nó không còn làm việc với pymongo3 và MongoDB3 + Bây giờ bạn cần thêm document_class=OrderedDict vào hàm tạo MongoClient. Sửa đổi câu trả lời ở trên cho khả năng tương thích pymongo3.

from collections import OrderedDict 
from pymongo import MongoClient 
import bson 

client = MongoClient(document_class=OrderedDict) 
sample_db = client['sample'] 
test_col = sample_db['test'] 

test_col.drop() 

data = OrderedDict([("one", 1), ("two", 2), ("three", 3), ("four", 4)]) 
test_col.insert(data) 
print(list(test_col.find({}, {'_id': 0}))) 

test_col.drop() 

data = bson.son.SON([("one", 1), ("two", 2), ("three", 3), ("four", 4)]) 
test_col.insert(data) 
print(list(test_col.find({}, {'_id': 0}))) 

Output:

[OrderedDict([(u'one', 1), (u'two', 2), (u'three', 3), (u'four', 4)])] 
[OrderedDict([(u'one', 1), (u'two', 2), (u'three', 3), (u'four', 4)])] 
2

Trong PyMongo v3.2 insert() đã bị phản đối và trong ví dụ này nó nên được thay thế bằng insert_one(). đang cập nhật là dưới đây:

from collections import OrderedDict 
from pymongo import MongoClient 
import bson 

client = MongoClient(document_class=OrderedDict) 
sample_db = client['sample'] 
test_col = sample_db['test'] 

test_col.drop() 

data = OrderedDict([("one", 1), ("two", 2), ("three", 3), ("four", 4)]) 
test_col.insert_one(data) 
print(list(test_col.find({}, {'_id': 0}))) 

test_col.drop() 

data = bson.son.SON([("one", 1), ("two", 2), ("three", 3), ("four", 4)]) 
test_col.insert_one(data) 
print(list(test_col.find({}, {'_id': 0}))) 

Output:

[OrderedDict([(u'one', 1), (u'two', 2), (u'three', 3), (u'four', 4)])] 
[OrderedDict([(u'one', 1), (u'two', 2), (u'three', 3), (u'four', 4)])] 
3

Một tiêu chuẩn find() trong PyMongo sẽ không trả về một đối tượng người là lĩnh vực đang trong thứ tự như đối tượng đó, nếu bạn lấy nó qua vỏ mongo.

Điều này là do, loại mặc định được trả về là Dict và thứ tự không được xác định.

Bạn có thể sử dụng SON như được đề xuất. Đây là cách tôi đã làm nó. Bây giờ, trật tự của trường sẽ được tôn trọng.

Điều này dành cho pymongo == 3.4.0

from bson.codec_options import CodecOptions 
from bson.son import SON 

opts = CodecOptions(document_class=SON) 
collection_son = mongo.db.collection.with_options(codec_options=opts) 

collection_son.find_one({"imsid": '12345'}) 
Các vấn đề liên quan