Pymongo:在 Response 中删除 $oid 的最佳方法
Pymongo: Best way to remove $oid in Response
我最近开始使用 Pymongo,现在我想找到在 Response 中删除 $oid 的最佳方法
当我使用find
时:
result = db.nodes.find_one({ "name": "Archer" }
并得到响应:
json.loads(dumps(result))
结果将是:
{
"_id": {
"$oid": "5e7511c45cb29ef48b8cfcff"
},
"about": "A jazz pianist falls for an aspiring actress in Los Angeles."
}
我的预期:
{
"_id": "5e7511c45cb29ef48b8cfcff",
"about": "A jazz pianist falls for an aspiring actress in Los Angeles."
}
如您所见,我们可以使用:
resp = json.loads(dumps(result))
resp['id'] = resp['id']['$oid']
但我认为这不是最好的方法。希望大家有更好的解决办法。
您可以利用聚合:
result = db.nodes.aggregate([{'$match': {"name": "Archer"}}
{'$addFields': {"Id": '$_id.oid'}},
{'$project': {'_id': 0}}])
data = json.dumps(list(result))
在这里,我使用 $addFields
添加了一个新字段 Id
,其中我引入了 oid
的值。然后我进行投影,在其中消除结果的 _id
字段。之后,当我得到一个光标时,我把它变成一个列表。
它可能不会像您希望的那样工作,但总体思路就在那里。
首先,响应中没有 $oid
。您看到的是 python 驱动程序将 _id
字段表示为 ObjectId 实例,然后 dumps()
方法将 ObjectId 字段表示为字符串格式。 $oid
位只是为了让您知道该字段是一个 ObjectId,您以后需要将其用于某些目的。
答案的下一部分取决于您要实现的目标。几乎可以肯定,您可以使用结果对象实现它而无需将其转换为 JSON.
如果你只想完全摆脱它,你可以这样做:
result = db.nodes.find_one({ "name": "Archer" }, {'_id': 0})
print(result)
给出:
{"name": "Archer"}
我正在使用某种形式的自定义处理程序。我设法删除 $oid
并仅用 id 字符串替换它:
# Custom Handler
def my_handler(x):
if isinstance(x, datetime.datetime):
return x.isoformat()
elif isinstance(x, bson.objectid.ObjectId):
return str(x)
else:
raise TypeError(x)
# parsing
def parse_json(data):
return json.loads(json.dumps(data, default=my_handler))
result = db.nodes.aggregate([{'$match': {"name": "Archer"}}
{'$addFields': {"_id": '$_id'}},
{'$project': {'_id': 0}}])
data = parse_json(result)
import re
def remove_oid(string):
while True:
pattern = re.compile('{\s*"$oid":\s*(\"[a-z0-9]{1,}\")\s*}')
match = re.search(pattern, string)
if match:
string = string.replace(match.group(0), match.group(1))
else:
return string
string = json_dumps(mongo_query_result)
string = remove_oid(string)
我最近开始使用 Pymongo,现在我想找到在 Response 中删除 $oid 的最佳方法
当我使用find
时:
result = db.nodes.find_one({ "name": "Archer" }
并得到响应:
json.loads(dumps(result))
结果将是:
{
"_id": {
"$oid": "5e7511c45cb29ef48b8cfcff"
},
"about": "A jazz pianist falls for an aspiring actress in Los Angeles."
}
我的预期:
{
"_id": "5e7511c45cb29ef48b8cfcff",
"about": "A jazz pianist falls for an aspiring actress in Los Angeles."
}
如您所见,我们可以使用:
resp = json.loads(dumps(result))
resp['id'] = resp['id']['$oid']
但我认为这不是最好的方法。希望大家有更好的解决办法。
您可以利用聚合:
result = db.nodes.aggregate([{'$match': {"name": "Archer"}}
{'$addFields': {"Id": '$_id.oid'}},
{'$project': {'_id': 0}}])
data = json.dumps(list(result))
在这里,我使用 $addFields
添加了一个新字段 Id
,其中我引入了 oid
的值。然后我进行投影,在其中消除结果的 _id
字段。之后,当我得到一个光标时,我把它变成一个列表。
它可能不会像您希望的那样工作,但总体思路就在那里。
首先,响应中没有 $oid
。您看到的是 python 驱动程序将 _id
字段表示为 ObjectId 实例,然后 dumps()
方法将 ObjectId 字段表示为字符串格式。 $oid
位只是为了让您知道该字段是一个 ObjectId,您以后需要将其用于某些目的。
答案的下一部分取决于您要实现的目标。几乎可以肯定,您可以使用结果对象实现它而无需将其转换为 JSON.
如果你只想完全摆脱它,你可以这样做:
result = db.nodes.find_one({ "name": "Archer" }, {'_id': 0})
print(result)
给出:
{"name": "Archer"}
我正在使用某种形式的自定义处理程序。我设法删除 $oid
并仅用 id 字符串替换它:
# Custom Handler
def my_handler(x):
if isinstance(x, datetime.datetime):
return x.isoformat()
elif isinstance(x, bson.objectid.ObjectId):
return str(x)
else:
raise TypeError(x)
# parsing
def parse_json(data):
return json.loads(json.dumps(data, default=my_handler))
result = db.nodes.aggregate([{'$match': {"name": "Archer"}}
{'$addFields': {"_id": '$_id'}},
{'$project': {'_id': 0}}])
data = parse_json(result)
import re
def remove_oid(string):
while True:
pattern = re.compile('{\s*"$oid":\s*(\"[a-z0-9]{1,}\")\s*}')
match = re.search(pattern, string)
if match:
string = string.replace(match.group(0), match.group(1))
else:
return string
string = json_dumps(mongo_query_result)
string = remove_oid(string)