Python Pymongo UUID搜索不返回确实存在的文档

Python Pymongo UUID搜索不返回确实存在的文档,python,pymongo,uuid,Python,Pymongo,Uuid,尝试在python中定义一个可以搜索给定UUID的函数,如下所示: def getid(in_id): return list(CollectionVar.find({"_id":UUID(in_id)})) 并传递UUID我可以从Studio 3T获取我知道存在的UUID,如下所示: db.getCollection("CollectionName").find({"_id":UUID("5002aa11-eeb7-4e68-a121-dd51497d2572")}) 上面的查询精

尝试在python中定义一个可以搜索给定UUID的函数,如下所示:

def getid(in_id):
    return list(CollectionVar.find({"_id":UUID(in_id)}))
并传递UUID我可以从Studio 3T获取我知道存在的UUID,如下所示:

db.getCollection("CollectionName").find({"_id":UUID("5002aa11-eeb7-4e68-a121-dd51497d2572")})
上面的查询精确地返回一个文档。python查询中的同一UUID完全不返回任何内容。我可以很容易地在其他(非UUID)字段中找到文档,例如,在前面的同一文档中,以下内容可以很好地工作:

def getname(fn,sn):
    return list(CollectionVar.find({"Firstname":re.compile(fn, re.IGNORECASE), "Surname":re.compile(sn, re.IGNORECASE)}))
这似乎是uuid.uuid类的问题,而不是pymongo问题?有人看到问题了吗


PyMongo版本3.6.1

您需要使用
ObjectId
而不是
UUID
。 试试这个,它对我有用:

from bson.objectid import ObjectId


def getid(in_id):
    return list(CollectionVar.find({"_id":ObjectId(in_id)}))

我是从
bson.binary.UUIDLegacy
类的docstring/comment中的
pymongo-2.8.1
中刮取的,可能有用

  >>> import uuid
  >>> from bson.binary import Binary, UUIDLegacy, UUID_SUBTYPE
  >>> my_uuid = uuid.uuid4()
  >>> coll = db.test
  >>> coll.uuid_subtype = UUID_SUBTYPE
  >>> coll.insert({'uuid': Binary(my_uuid.bytes, 3)})
  ObjectId('...')
  >>> coll.find({'uuid': my_uuid}).count()
  0
  >>> coll.find({'uuid': UUIDLegacy(my_uuid)}).count()
  1
  >>> coll.find({'uuid': UUIDLegacy(my_uuid)})[0]['uuid']
  UUID('...')
  >>>
  >>> # Convert from subtype 3 to subtype 4
  >>> doc = coll.find_one({'uuid': UUIDLegacy(my_uuid)})
  >>> coll.save(doc)
  ObjectId('...')
  >>> coll.find({'uuid': UUIDLegacy(my_uuid)}).count()
  0
  >>> coll.find({'uuid': {'$in': [UUIDLegacy(my_uuid), my_uuid]}}).count()
  1
  >>> coll.find_one({'uuid': my_uuid})['uuid']
  UUID('...')

我已经解决了这个问题。对于遇到此问题的任何其他人,解决方案如下:

from bson.binary import Binary, UUID_SUBTYPE

def getcust(inid):
    newuuid=uuid.UUID(inid).bytes
    return list(DealershipConsumer.find({"_id": Binary(bytes(bytearray(newuuid)), UUID_SUBTYPE)}))

UUID_SUBTYPE需要设置为您使用的UUID的任何子类型-在我的示例中为4。

您可以在获取数据库时指定您使用的UUID类型:

import bson
import pymongo

mongo_client = pymongo.MongoClient(mongo_uri, document_class=dict)
db = mongo_client.get_database(                              
    "my_db_name",                                                          
    bson.codec_options.CodecOptions(uuid_representation=bson.binary.UUID_SUBTYPE),
) 
如果您想在使用UUID时阅读更多关于Mongo最佳实践的信息,可能会有所帮助


此外,这里还有一些关于编解码器选项的信息。问题是PyMongo默认使用传统的UUID值编码/解码方法。您可能希望将PyMongo客户端配置为使用更现代、跨语言兼容的“标准”UUID表示:

client = MongoClient(MONGODB_URI, uuidRepresentation="standard")
现在,您应该能够使用Python
uuid.uuid
实例直接查询:

from uuid import UUID

items = client["item_database"]["items"].find_one({
    "uuid": UUID("187382af-1369-43e6-a0ba-d345886c986c")
})

“InvalidId:'5002aa11-eeb7-4e68-a121-dd51497d2572'不是有效的ObjectId,它必须是12字节的输入或24个字符的十六进制字符串”是使用bson.ObjectId的ObjectId类时的错误消息。我拿错了吗?@MichaelBrown你确定你的“身份证”是UUID吗?如果我没有弄错的话,它是由mongo自动生成的,看起来像“507f191e810c19729de860ea”。你能看看这个吗?从Studio 3T(搜索UUID(“5002aa11-eeb7-4e68-a121-dd51497d2572”)可以正常工作)注意,你可以(也应该)从UUID字节中提取UUID版本,而不是假设一个固定值。