我使用mongoengine作为ORM和flask应用程序.模型类是这样定义的

class MyData(db.Document):
    task_id = db.StringField(max_length=50, required=True)
    url = db.URLField(max_length=500,required=True,unique=True)
    organization = db.StringField(max_length=250,required=True)
    val = db.StringField(max_length=50, required=True)

字段组织可以是重复的,我想得到与另一个字段中的值相关的重复计数.例如,如果mongodb中的数据如下

[{"task_id":"as4d2rds5","url":"https:example1.com","organization":"Avengers","val":"null"},
 {"task_id":"rfre43fed","url":"https:example1.com","organization":"Avengers","val":"valid"},
 {"task_id":"uyje3dsxs","url":"https:example2.com","organization":"Metro","val":"valid"},
 {"task_id":"ghs563vt6","url":"https:example1.com","organization":"Avengers","val":"invalid"},
 {"task_id":"erf6egy64","url":"https:example2.com","organization":"Metro","val":"null"}]

然后我使用

data = MyData.objects()

我想要一个像这样的回应

[{"url":"https:example1.com","Avengers":{"valid":1,"null":1,"invalid":1}},{"url":"https:example2.com",Metro":{"valid":1,"null":1,"invalid":0}}]

我试着

db.collection.aggregate([
  {
    "$group": {
      "_id": "$organization",
      "count": [
        {
          "null": {
            "$sum": 1
          },
          "valid": {
            "$sum": 1
          },
          "invalid": {
            "$sum": 1
          }
        }
      ]
    }
  }
])

但我犯了个错误

The field 'count' must be an accumulator object

推荐答案

也许是这样的:

db.collection.aggregate([
{
  "$group": {
  "_id": {
    k: "$organization",
    v: "$val"
   },
  "cnt": {
    $sum: 1
   }
  }
 },
 {
  $project: {
    _id: 0,
    k: "$_id.k",
    o: {
      k: "$_id.v",
      v: "$cnt"
    }
   }
  },
 {
   $group: {
    _id: "$k",
    v: {
      $push: "$o"
    }
  }
},
{
  $addFields: {
    v: {
      "$arrayToObject": "$v"
    }
  }
},
{
  $project: {
    _id: 0,
    new: [
      {
        k: "$_id",
        v: "$v"
      }
    ]
  }
},
{
  "$addFields": {
    "new": {
      "$arrayToObject": "$new"
    }
  }
},
{
 "$replaceRoot": {
   "newRoot": "$new"
 }
}
])

解释:

  1. 分组计算
  2. arrayToObject的项目
  3. 组加入值
  4. 再来一次
  5. 另外计划
  6. arrayToObject以形成最终对象
  7. 再来一次
  8. replaceRoot将对象移动到根.

附笔.

playground1

缺少值的选项(如果可能的值固定为null、valid、invalid):

   {
   $addFields: {
     v: {
    "$mergeObjects": [
      {
        "null": 0,
        valid: 0,
        invalid: 0
      },
      {
        "$arrayToObject": "$v"
      }
    ]
   }
  }
 }

playground2

++网址:

playground3

Python相关问答推荐

Altair -箱形图边界设置为黑色,中线设置为红色

在Arrow上迭代的快速方法.Julia中包含3000万行和25列的表

在Python和matlab中显示不同 colored颜色 的图像

无法使用equals_html从网址获取全文

如何根据另一列值用字典中的值替换列值

将DF中的名称与另一DF拆分并匹配并返回匹配的公司

运行回文查找器代码时发生错误:[类型错误:builtin_index_or_system对象不可订阅]

比较两个数据帧并并排附加结果(获取性能警告)

Odoo 14 hr. emergency.public内的二进制字段

为什么tkinter框架没有被隐藏?

对整个 pyramid 进行分组与对 pyramid 列子集进行分组

运行总计基于多列pandas的分组和总和

如何让程序打印新段落上的每一行?

Pandas计数符合某些条件的特定列的数量

如何在Polars中从列表中的所有 struct 中 Select 字段?

判断solve_ivp中的事件

在Python中调用变量(特别是Tkinter)

为什么if2/if3会提供两种不同的输出?

跳过嵌套JSON中的级别并转换为Pandas Rame

freq = inject在pandas中做了什么?''它与freq = D有什么不同?''