PyMongo: TypeError: spec 必须是 dict 的实例

1 投票
2 回答
6180 浏览
提问于 2025-05-01 03:57

我有一串MongoDB的ID

id_list = [{u'_id': u'0'}, {u'_id': u'1'}, {u'_id': u'2'}, {u'_id': u'3'}, {u'_id': u'4'}]

我想一次性向MongoDB发送查询,并按我提供的顺序获取匹配的文档。但是,下面的代码出现了一个错误,提示TypeError: spec must be an instance of dict

from pymongo import MongoClient

if __name__ == '__main__':

    db = MongoClient()

    sDB = db.test.users
    id_list = [{u'_id': u'0'}, {u'_id': u'1'}, {u'_id': u'2'}, {u'_id': u'3'}, {u'_id': u'4'}]
    print list(sDB.find(id_list[0:2]))
暂无标签

2 个回答

2

MongoDB在搜索时使用字典,而你提供的是一个数组:

你的例子:

id_list[0:2] is [{u'_id': u'0'}, {u'_id': u'1'}]

其实你可以用 $in 来处理这个:

db.test.users.find({'_id':{'$in': ["0", "1", "2"]}})
1

在使用MongoDB查询时,必须遵循特定的语法,也就是说:

collection.find({"_id": {"$in": [id1, id2, ..., idN]}})

首先,你需要获取一个只包含所需ID的列表,而不是一个包含字典的列表:

needed_ids_only = map(lambda x: x['_id'], id_list[0:2])
# needed_ids_only is now == [u'0', u'1']

然后,把这个列表提供给"$in"操作符:

print list(sDB.find({"_id": {"$in": needed_ids_only}}))

值得一提的是,如果你的文档的_id是字符串类型,就像你在问题中提到的,那就没问题。但如果你指的是ObjectId类型,那么在查询之前需要先转换成ObjectId。

所以,如果你的文档看起来是这样的:

> db.users.find().pretty()
{
    _id: '0',
    // ...
},
{
    _id: '1',
    // ...
},
// ...

那就没问题。但如果它们看起来是这样的:

> db.users.find().pretty()
{
    _id: ObjectId('0'),
    // ...
},
{
    _id: ObjectId('1'),
    // ...
},
// ...

那么就需要把_id的值转换成ObjectId:

from bson import ObjectId
needed_ids_only = map(lambda x: ObjectId(x['_id']), id_list[0:2])

撰写回答