mongoengine从嵌入文档列表中获取值

时间:2015-07-30 17:13:08

标签: python mongodb mongodb-query aggregation-framework mongoengine

给定数百个具有以下结构的文档(如下所示),为特定参数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
        }, ...

    ]
}

到目前为止,我的进展如下:

  1. 获取包含特定参数的所有文档。

    parameter = Parameter.objects.get_or_404(id = args.get('parameter'))
    data = Record.objects(values__parameter = parameter).all()
    
  2. 转换为列表。这种方式看起来非常低效。如果有人有更好的方法,请告诉我!

    list = [] 
    for i in data:
        for index, item in enumerate(i.values):
            if item['parameter'] == parameter:
                list.append({'date': i.date, 'value': item['value']})
    

1 个答案:

答案 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对象。