我的文档具有如下架构:
{
"user_id": 123,
"services":[
{"name": "test",
"data": ...
},
{"name": "test1",
"data": ...
},
{"name": "test2",
"data": ...
}
]
}
我正在尝试通过名称获取特定用户ID的服务,该用户ID返回如下:
{"name": "test2",
"data": ...
}
我很难全神贯注于如何执行此操作,并且似乎不需要像这样简单的操作进行汇总,但是也许我错了。我确定投影可以在find_one
语句中使用,但不确定使用什么。我正在使用Motor不确定是否有帮助。
我尝试过:
async def get_service_by_name(user_id, name):
return await db.guilds.find_one({
'user_id': 123,
'services': {'$elemMatch': {'name': "test"}}},
{'user_id: 0, 'services.$': 1}))
但这返回:
{"services":[{"name" : "test", "data" : "blah" }]}
那很好,因为它接近我想要的,而我要做的就是:
service = await get_service_by_name(123, "test")
service = service['service'][0]
但是有没有办法在没有聚合的情况下像服务一样取回数据呢?如果没有,那么聚合应该是什么样子?
修改
我想出了一个可以做到这一点的聚合方法,但是想确保没有更好的方法:
await db.guilds.aggregate([
{'$unwind': '$services'},
{'$match':{
'_id': 123,
'services.name': "test"}},
{'$project': {
'_id': 0,
'name': '$services.name',
'data': '$services.data'}}
])
答案 0 :(得分:3)
您需要运行$unwind从services
获取单个文档,然后运行$replaceRoot将其提升到根级别:
db.guilds.aggregate([
{
$match: { user_id: 123, "services.name": "test" }
},
{
$unwind: "$services"
},
{
$match: { "services.name": "test" }
},
{
$replaceRoot: { newRoot: "$services" }
}
])