使用 pymongo 和 Flask 从 MongoDB 聚合和计算结果中的项目
Aggregate and Count Items in a Result from MongoDB using pymongo & Flask
我正在尝试 return 在 Flask 环境中使用 pymongo MongoDB 得到一个简单的 JSON 结果。这是我正在做的:
def myResults():
myCollection = db["my_data"]
results = list(myCollection.find({},{"ID":1,"Response":1,"_id":0}))
return jsonify(results=results)
当我这样做时,我得到以下结果。仅供参考 "ID"
基本上是一个虚构的唯一标识符。
{
"result": [
{
"ID": 1,
"Response": "A"
},
{
"ID": 4,
"Response": "B"
},
{
"ID": 3,
"Response": "A"
},
]
} // and so on...
我想汇总特定 ID 的所有回复并显示计数。我猜看起来像这样的东西(或者如果有更好的方法):
{
"result": [
{
"ID": 1,
"A": 2,
"B": 1,
"C": 5,
"Total": 8
},
{
"ID": 4,
"A": 0,
"B": 5,
"C": 18,
"Total": 23
},
{
"ID": 3,
"A": 12,
"B": 6,
"C": 8,
"Total": 26
},
]
}
Whosebug 上有人推荐使用 aggregate()
。但这对我来说并不是很有效。
allResults = surveyCollection.aggregate([
{"$unwind": result },
{"$group": {"_id": result.ID, "A": {"$sum": 1}, "B": {"$sum": 1}}},
{"$group": {"_id": None, "result": {"$push": {"ID": "$ID", "A": "$A", "B": "$B"}}}}
])
return jsonify(allResults)
我得到一个错误:AttributeError: 'list' object has no attribute 'ID'
。
有没有更简单的方法,只用find()
或count()
?
将 result.ID 替换为 "result.ID"。没有引号 python 将查找变量 result.ID(不存在)而不是向服务器发送文字字符串 "result.ID".
聚合框架引用所有带有$
前缀的字段名称。这不是 "python" 代码,而是 "aggregation pipeline" 操作,因此它只是一个要转换为 BSON 的数据结构。
allResults = surveyCollection.aggregate([
{ "$group": {
"_id": {
"ID": "$ID",
"type": "$Response"
},
"count": { "$sum": 1 },
}},
{ "$group": {
"_id": "$_id.ID",
"A": { "$sum": { "$cond": [{ "$eq": [ "$_id.type", "A" ]}, "$count", 0 ] } },
"B": { "$sum": { "$cond": [{ "$eq": [ "$_id.type", "B" ]}, "$count", 0 ] } },
"C": { "$sum": { "$cond": [{ "$eq": [ "$_id.type", "C" ]}, "$count", 0 ] } },
"Total": { "$sum": "$count" }
}}
])
return jsonify(allResults)
根据您提供给我们的三个文件,这个结果:
{ "_id" : 1, "A" : 1, "B" : 0, "C" : 0, "Total" : 1 }
{ "_id" : 4, "A" : 0, "B" : 1, "C" : 0, "Total" : 1 }
{ "_id" : 3, "A" : 1, "B" : 0, "C" : 0, "Total" : 1 }
所以你最后开始做正确的事,但中间有点偏离轨道。
你不能在这里做的是"dynanically"在聚合框架中创建字段,所以你需要指定所有必需的"properties"并测试条件如图。如果您不能接受它,那么您需要这种格式的 mapReduce。我个人会这样做更简单:
allResults = surveyCollection.aggregate([
{ "$group": {
"_id": {
"ID": "$ID",
"type": "$Response"
},
"count": { "$sum": 1 }
}},
{ "$group": {
"_id": "$_id.ID",
"results": {
"$push": {
"type": "$_id.type",
"count": "$count"
}
},
"Total": { "$sum": "$count" }
}}
])
return jsonify(allResults)
不同的输出格式,但相同的基本信息和简单:
{ "_id" : 1, "results" : [ { "type" : "A", "count" : 1 } ], "Total" : 1 }
{ "_id" : 4, "results" : [ { "type" : "B", "count" : 1 } ], "Total" : 1 }
{ "_id" : 3, "results" : [ { "type" : "A", "count" : 1 } ], "Total" : 1 }
顺便说一句。这实际上看起来像是来自聚合结果,因此可能是时候重新访问创建源代码的代码了。
我正在尝试 return 在 Flask 环境中使用 pymongo MongoDB 得到一个简单的 JSON 结果。这是我正在做的:
def myResults():
myCollection = db["my_data"]
results = list(myCollection.find({},{"ID":1,"Response":1,"_id":0}))
return jsonify(results=results)
当我这样做时,我得到以下结果。仅供参考 "ID"
基本上是一个虚构的唯一标识符。
{
"result": [
{
"ID": 1,
"Response": "A"
},
{
"ID": 4,
"Response": "B"
},
{
"ID": 3,
"Response": "A"
},
]
} // and so on...
我想汇总特定 ID 的所有回复并显示计数。我猜看起来像这样的东西(或者如果有更好的方法):
{
"result": [
{
"ID": 1,
"A": 2,
"B": 1,
"C": 5,
"Total": 8
},
{
"ID": 4,
"A": 0,
"B": 5,
"C": 18,
"Total": 23
},
{
"ID": 3,
"A": 12,
"B": 6,
"C": 8,
"Total": 26
},
]
}
Whosebug 上有人推荐使用 aggregate()
。但这对我来说并不是很有效。
allResults = surveyCollection.aggregate([
{"$unwind": result },
{"$group": {"_id": result.ID, "A": {"$sum": 1}, "B": {"$sum": 1}}},
{"$group": {"_id": None, "result": {"$push": {"ID": "$ID", "A": "$A", "B": "$B"}}}}
])
return jsonify(allResults)
我得到一个错误:AttributeError: 'list' object has no attribute 'ID'
。
有没有更简单的方法,只用find()
或count()
?
将 result.ID 替换为 "result.ID"。没有引号 python 将查找变量 result.ID(不存在)而不是向服务器发送文字字符串 "result.ID".
聚合框架引用所有带有$
前缀的字段名称。这不是 "python" 代码,而是 "aggregation pipeline" 操作,因此它只是一个要转换为 BSON 的数据结构。
allResults = surveyCollection.aggregate([
{ "$group": {
"_id": {
"ID": "$ID",
"type": "$Response"
},
"count": { "$sum": 1 },
}},
{ "$group": {
"_id": "$_id.ID",
"A": { "$sum": { "$cond": [{ "$eq": [ "$_id.type", "A" ]}, "$count", 0 ] } },
"B": { "$sum": { "$cond": [{ "$eq": [ "$_id.type", "B" ]}, "$count", 0 ] } },
"C": { "$sum": { "$cond": [{ "$eq": [ "$_id.type", "C" ]}, "$count", 0 ] } },
"Total": { "$sum": "$count" }
}}
])
return jsonify(allResults)
根据您提供给我们的三个文件,这个结果:
{ "_id" : 1, "A" : 1, "B" : 0, "C" : 0, "Total" : 1 }
{ "_id" : 4, "A" : 0, "B" : 1, "C" : 0, "Total" : 1 }
{ "_id" : 3, "A" : 1, "B" : 0, "C" : 0, "Total" : 1 }
所以你最后开始做正确的事,但中间有点偏离轨道。
你不能在这里做的是"dynanically"在聚合框架中创建字段,所以你需要指定所有必需的"properties"并测试条件如图。如果您不能接受它,那么您需要这种格式的 mapReduce。我个人会这样做更简单:
allResults = surveyCollection.aggregate([
{ "$group": {
"_id": {
"ID": "$ID",
"type": "$Response"
},
"count": { "$sum": 1 }
}},
{ "$group": {
"_id": "$_id.ID",
"results": {
"$push": {
"type": "$_id.type",
"count": "$count"
}
},
"Total": { "$sum": "$count" }
}}
])
return jsonify(allResults)
不同的输出格式,但相同的基本信息和简单:
{ "_id" : 1, "results" : [ { "type" : "A", "count" : 1 } ], "Total" : 1 }
{ "_id" : 4, "results" : [ { "type" : "B", "count" : 1 } ], "Total" : 1 }
{ "_id" : 3, "results" : [ { "type" : "A", "count" : 1 } ], "Total" : 1 }
顺便说一句。这实际上看起来像是来自聚合结果,因此可能是时候重新访问创建源代码的代码了。