簡體   English   中英

使用pymongo和Flask匯總和計數MongoDB結果中的項目

[英]Aggregate and Count Items in a Result from MongoDB using pymongo & Flask

我試圖在Flask環境中使用pymongo從MongoDB返回簡單的JSON結果。 這是我在做什么:

def myResults():
    myCollection = db["my_data"]
    results = list(myCollection.find({},{"ID":1,"Response":1,"_id":0}))
    return jsonify(results=results)

當我這樣做時,我得到以下結果。 FYI "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
    },
  ]
}

StackOverflow上的某人建議使用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()沒有更簡單的方法?

聚合框架引用帶有$前綴的所有字段名稱。 這不是“ python”代碼,而是“聚合管道”操作,因此,這只是要轉換為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 }

因此,您從一開始就做正確的事情,但中間卻偏離了軌道。

您在這里不能做的是在聚合框架中“動態地”創建字段,因此您需要指定所有必需的“屬性”並使用所示條件進行測試。 如果無法忍受,則需要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 }

BTW。 實際上,這看起來像是來自聚合結果,因此可能是時候重新訪問創建源代碼的時候了。

將result.ID替換為“ result.ID”。 如果沒有引號,python將查找變量result.ID(不存在),而不是向服務器發送文字字符串“ result.ID”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM