如何为MongoDB文档子字段的字典列表添加独立ObjectId?
为MongoDB文档子数组元素添加独立ObjectId
问题
我在脚本中创建了IndividualRating类的对象列表,希望将其保存/更新到MongoDB文档的子字段中。类定义如下:
class IndividualRating: def __init__(self, place=0, player="", team="", games="", legs=""): self.place = place self.player = player self.team = team self.games = games self.legs = legs
生成对象列表并转为字典的代码:
ratings = [] for row in rows: rating = IndividualRating() # 此处赋值 ratings.append(rating.__dict__)
使用以下代码保存到MongoDB:
def save_ratings(league_id, season_id, ratings): database.individualratings.update_one( { "seasonId": season_id, "leagueId": league_id }, { "$setOnInsert": { "seasonId": season_id, "leagueId": league_id }, "$set": { "player": ratings } }, upsert=True )
这段代码可以正常运行,但player子字段下的每个对象缺少独立的ObjectId,期望的文档结构如下:
{ _id: ObjectId('someLongId'), seasonId: 56267, leagueId: 27273, player: [ { _id: ObjectId('uniqueId1'), place: 1, player: "Some Player Name", team: "Some Team Name", games: "2:0", legs: "10:0" }, { _id: ObjectId('uniqueId2'), place: 2, player: "Some Player Name", team: "Some Team Name", games: "2:0", legs: "10:0" } ] }
需要实现为MongoDB文档子字段中的字典列表每个条目添加独立ObjectId。
解决方案
方法1:生成字典时手动添加ObjectId
在将IndividualRating对象转为字典的环节,直接为每个字典添加_id字段,使用bson.ObjectId()生成唯一标识。
修改生成列表的代码:
from bson import ObjectId # 导入ObjectId类 ratings = [] for row in rows: rating = IndividualRating() # 完成赋值逻辑 rating_dict = rating.__dict__ rating_dict["_id"] = ObjectId() # 为每个评分对象添加独立ObjectId ratings.append(rating_dict)
后续调用原save_ratings函数保存即可,此时player数组内的每个元素都会带有专属的_id。
方法2:数据库层面补全ObjectId(针对已有数据)
如果需要给已存入数据库的文档补加子元素的_id,可以利用MongoDB的聚合更新操作,通过$map和$mergeObjects为数组元素生成ObjectId:
def add_missing_player_ids(league_id, season_id): database.individualratings.update_one( {"seasonId": season_id, "leagueId": league_id}, [ { "$set": { "player": { "$map": { "input": "$player", "as": "item", "in": { "$mergeObjects": [ "$$item", {"_id": ObjectId()} ] } } } } } ] )
该操作会为player数组中所有无_id的元素生成新的唯一ID,已有_id的元素则保留原值。
内容的提问来源于stack exchange,提问作者Tobias
相关产品推荐
相关产品推荐

