给定数百个具有以下结构的文档(如下所示),为特定参数x生成[date,value]列表的最佳方法是什么?
{_id: ObjectId(...),
date: 2014-12-04 21:25:43,
values: [
{ parameter: ObjectId(...),
value: 34.5
},
{ parameter: ObjectId(...),
value: 1.3
},
{ parameter: ObjectId(...),
value: 2.0
}, ...
]
}
到目前为止,我的进展如下:
获取包含特定参数的所有文档。
parameter = Parameter.objects.get_or_404(id = args.get('parameter'))
data = Record.objects(values__parameter = parameter).all()
转换为列表。这种方式看起来非常低效。如果有人有更好的方法,请告诉我!
list = []
for i in data:
for index, item in enumerate(i.values):
if item['parameter'] == parameter:
list.append({'date': i.date, 'value': item['value']})
答案 0 :(得分:0)
另一种方法是使用aggregation framework直接获取匹配参数:
.cpp
如果可以,可能会更有效率:
AComplexClass
通过$unwind
将数组“有效地”“规范化”为单个文档,并“过滤”该列表,仅供您处理的匹配元素。 $redact
允许在进行非规范化之前从数组中“修剪”元素,这样可以节省一些空间,并且通常比不匹配的数组元素去标准化后的过滤更有效。
如果您希望在聚合管道的末尾添加$project
,也可以将结果字段限制为您想要的那些:
Record._get_collection().aggregate([
{ "$match": { "values.parameter": parameter } },
{ "$unwind": "$values" },
{ "$match": { "values.parameter": parameter } }
])
这可以为您节省一些从服务器传回应用程序的内容,以及无需在代码中操作结果。
Record._get_collection().aggregate([
{ "$match": { "values.parameter": parameter } },
{ "$redact": {
"$cond": [
{ "$eq": [{ "$ifNull": [ "$parameter", parameter ] }, parameter ] },
"$$DESCEND",
"$$PRUNE"
]
}},
{ "$unwind": "$values" }
])
有一种无法访问底层pymongo驱动程序的原始collection object的方法。这反过来允许访问那里的.aggregate()
方法。所有对象都是在普通列表中返回的普通python对象。