簡體   English   中英

Pymongo UUID 搜索不返回確實存在的文檔

[英]Pymongo UUID search not returning documents that definitely exist

嘗試在 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

問題是 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")
})

我已經解決了這個問題。 對於遇到此問題的任何其他人,解決方案如下:

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。

您可以在獲取 db 時指定您正在使用的 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 最佳實踐的更多信息, 這篇文章可能會有所幫助。

另外,這里是關於codec_options 的文檔

我在bson.binary.UUIDLegacy類的文檔字符串/評論中從pymongo-2.8.1bson.binary.UUIDLegacy了這個,可能有用

  >>> 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('...')

您需要使用ObjectId而不是UUID 試試這個,它對我有用:

from bson.objectid import ObjectId


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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM