Python 如何在pymongo中获得有序词典?

Python 如何在pymongo中获得有序词典?,python,data-structures,pymongo,bson,Python,Data Structures,Pymongo,Bson,我正试着在Pymongo订购字典。我已经读过了,可以用bson.son.son完成。这些文件是 然而,我似乎无法让它工作。谷歌对此没有太多关注。关于首先配置pymongo以告诉它使用SON对象,有一些讨论,但没有示例。一位朋友建议在你查找时传递一个参数。他不记得了 with mongo_manager.Collection(CFG.db, 'Users') as users: account = users.find_on

我正试着在Pymongo订购字典。我已经读过了,可以用bson.son.son完成。这些文件是

然而,我似乎无法让它工作。谷歌对此没有太多关注。关于首先配置pymongo以告诉它使用SON对象,有一些讨论,但没有示例。一位朋友建议在你查找时传递一个参数。他不记得了

with mongo_manager.Collection(CFG.db, 'Users') as users:                                 
    account = users.find_one({'_id': _id, 'DOC':'OrderedDict})
我能够创建子对象。但是,当它们被插入数据库,然后又返回时,它们只是普通的dict

我真的不知道该给你们什么样的代码示例,因为我真的不知道从哪里开始。每次我添加新用户时,下面的代码段都会创建一个空的子对象。“sub_users”对象也是使用SON创建的。当我从数据库读回account文档时,它们只是普通的python指令

    account['sub_users'][sub_user_name] = bson.SON()
    with mongo_manager.Collection(CFG.db, 'Users') as users:
        users.save(account)
可能是一个参数,通过这样的查找来配置?这是我朋友的建议,但他记不得了

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

有什么想法吗?

您可以使用
bson.son.son
OrderedDict
来存储已订购的dict

并使用
作为\u class=OrderedDict
选项检索数据

以下是一个例子:

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)))
输出:

[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)])]
[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)])]
[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)])]

上述解决方案适用于较早版本的MongoDB和pymongo驱动程序,但它不再适用于pymongo3和MongoDB3+,您现在需要将
document\u class=OrderedDict
添加到MongoClient构造函数中。为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})))
输出:

[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)])]
[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)])]
[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)])]

在PyMongo v3.2中,
insert()
已被弃用,在本例中,应将其替换为
insert\u one()
。更新代码如下:

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})))
输出:

[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)])]
[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)])]
[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)])]
PyMongo中的标准find()将不会返回与该对象的字段顺序相同的对象(如果通过mongo shell检索)

这是因为,返回的默认类型是Dict,并且没有定义顺序

你可以按照建议使用SON。我是这样做的。 现在,现场秩序将得到尊重

这是针对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'})

使用
OrderedDict
SON
对象在性能上有什么区别吗?查看源代码(、和),它们都是
dict
的子类,但是
orderedict
有一个C实现(使用纯Python实现作为后备),而
SON
似乎只有一个Python实现……我得到了一个错误-“\uu init\uuuu()得到了一个意外的关键字参数'as\u class'”.@KalyanamRajashree那是因为这个已经被移除了