如何将两个mongodb查询合并为一个

发布于 2025-02-07 19:51:44 字数 2566 浏览 1 评论 0原文

如下所示,我有两个mongoDB骨料查询。

以下查询给了我总数失败的计数,而截面类型的

db.Departments.aggregate([
    {
        $match: {$and: [{"subject.failed": {$eq: 'true'}}, {"section": {$eq: 'A'}}]}
    },
    {
        $group: {
            _id: {"sectionType": "$sectionType"},
            "COUNT(*)": {$sum: 1}
        }
    },
    {
        $project: {"totalFailed": "$COUNT(*)", "$sectionType": "$_id.$sectionType", "_id": 0}
    }
])

查询查找了我们从上面查询中获得的部分类型参加考试的总数,

db.Departments.aggregate([
    {
        $match: {$and: [{"sectionType": {$eq: 'Section Type From the Previous query result'}}, {"section": {$eq: 'A'}}]}
    },
    {
        $group: {
            _id: null,
            "COUNT(*)": {$sum: 1}
        }
    },
    {
        $project: {"totalCount": "$COUNT(*)", "_id": 0}
    }
])
 

这两个查询都可以正常工作,但是我会想知道我是否有其他方法可以加入这两个查询并以其他更好的方式重写

样本数据,如

doc 1

{
        "section": "A",
        "sectionType": "typeA",
        "subject": [
          {
            "failed": "true",
            "subject_name": "Name A",
            "subject_staff_count": "1245",
            "subject_id": "a1111"
          },
          {
            "failed": "true",
            "subject_name": "Name B",
            "subject_staff_count": "2222",
            "subject_id": "a2222"
          }
        ]
      }

doc 2

 {
    "section": "A",
    "sectionType": "typeA",
    "subject": [
      {
        "failed": "true",
        "subject_name": "Name B",
        "subject_staff_count": "3333",
        "subject_id": "a331"
      },
      {
        "failed": "true",
        "subject_name": "Name C",
        "subject_staff_count": "4444",
        "subject_id": "a44422"
      }
    ]
  }

文档3

{
    "section": "A",
    "sectionType": "typeA",
    "subject": []
  }

第一个查询结果的

|-------------|-------------|
| sectionType | totalFailed |
|-------------|-------------|
|    typeA    |      2      | 
|_____________|_____________|

第一个查询结果我们获得了sectionType typea ,通过使用,我们获得了第二个查询结果

|-------------|
| totalCount  |
|-------------|
|     3       | 
|_____________|

预期结果

,我试图获得的预期结果

是第一个查询的结果

|-------------|-------------|
| totalFailed |  totalCount |
|-------------|-------------|
|      2      |      3      | 
|_____________|_____________|

I have two mongodb aggregate query as shown below.

The below query gives me the count of total failed and the sectionType

db.Departments.aggregate([
    {
        $match: {$and: [{"subject.failed": {$eq: 'true'}}, {"section": {$eq: 'A'}}]}
    },
    {
        $group: {
            _id: {"sectionType": "$sectionType"},
            "COUNT(*)": {$sum: 1}
        }
    },
    {
        $project: {"totalFailed": "$COUNT(*)", "$sectionType": "$_id.$sectionType", "_id": 0}
    }
])

The below query find the total who attended the exam in the section type which we got from the above query

db.Departments.aggregate([
    {
        $match: {$and: [{"sectionType": {$eq: 'Section Type From the Previous query result'}}, {"section": {$eq: 'A'}}]}
    },
    {
        $group: {
            _id: null,
            "COUNT(*)": {$sum: 1}
        }
    },
    {
        $project: {"totalCount": "$COUNT(*)", "_id": 0}
    }
])
 

Both queries are working fine, but I would like to know if there is any other way I can join these two queries and rewrite in any other better way

A sample data is as given below

doc 1

{
        "section": "A",
        "sectionType": "typeA",
        "subject": [
          {
            "failed": "true",
            "subject_name": "Name A",
            "subject_staff_count": "1245",
            "subject_id": "a1111"
          },
          {
            "failed": "true",
            "subject_name": "Name B",
            "subject_staff_count": "2222",
            "subject_id": "a2222"
          }
        ]
      }

doc 2

 {
    "section": "A",
    "sectionType": "typeA",
    "subject": [
      {
        "failed": "true",
        "subject_name": "Name B",
        "subject_staff_count": "3333",
        "subject_id": "a331"
      },
      {
        "failed": "true",
        "subject_name": "Name C",
        "subject_staff_count": "4444",
        "subject_id": "a44422"
      }
    ]
  }

doc 3

{
    "section": "A",
    "sectionType": "typeA",
    "subject": []
  }

The result of 1st Query

|-------------|-------------|
| sectionType | totalFailed |
|-------------|-------------|
|    typeA    |      2      | 
|_____________|_____________|

From the first query result we get sectionType typeA, by using that we get the second query result

|-------------|
| totalCount  |
|-------------|
|     3       | 
|_____________|

Expected Result

My expected result which I am trying to get is

The result of 1st Query

|-------------|-------------|
| totalFailed |  totalCount |
|-------------|-------------|
|      2      |      3      | 
|_____________|_____________|

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

话少情深 2025-02-14 19:51:44

标题确实令人困惑。您没有合并2个查询,需要2个计数 - 总和有条件。我相信您会在这样的问题上找到很多答案noreferrer“> $ cond 在聚合器中:

db.Departments.aggregate([
  {
    $match: {
      "section": "A"
    }
  },
  {
    $group: {
      _id: "$sectionType",
      "totalFailed": {
        $sum: {
          $cond: [
            {
              $eq: [
                "$subject.failed",
                "true"
              ]
            },
            1,
            0
          ]
        }
      },
      "total": {
        $sum: 1
      }
    }
  },
  {
    $project: {
      "totalFailed": 1,
      "sectionType": "$_id",
      "total": 1,
      "_id": 0
    }
  }
])

作为旁注,原始查询建议您从SQL复制它们。您可能会发现带有结构的文档的结果非常出乎意料。

管道中的初始$匹配阶段将匹配所有文档,其中至少1个项目主题数组匹配中,即失败。

如果您打算每项对象计数,则需要添加{“ $ undind”:“ $ object”}, 阶段,阶段。

The title is really confusing. You are not merging 2 queries, you need 2 counts - total and conditional. I am sure you would find plenty of answers to that question on SO, all about using $cond in the aggregator:

db.Departments.aggregate([
  {
    $match: {
      "section": "A"
    }
  },
  {
    $group: {
      _id: "$sectionType",
      "totalFailed": {
        $sum: {
          $cond: [
            {
              $eq: [
                "$subject.failed",
                "true"
              ]
            },
            1,
            0
          ]
        }
      },
      "total": {
        $sum: 1
      }
    }
  },
  {
    $project: {
      "totalFailed": 1,
      "sectionType": "$_id",
      "total": 1,
      "_id": 0
    }
  }
])

As a side note, the original queries suggest you copied them from SQL. You may find results quite unexpected for documents with your structure.

The initial $match stage in your pipelines will match all documents where at least 1 item in the subject array matches, i.e. failed.

If you intend to count per-subject, you need to add {"$unwind": "$subject"}, stage right after the $match.

Spring初心 2025-02-14 19:51:44

您可以使用$ lookup执行第二查询。只需将您的第二个查询放入子pipeline中

db.Departments.aggregate([
  {
    $match: {
      $and: [
        {
          "subject.failed": {
            $eq: "true"
          }
        },
        {
          "section": {
            $eq: "A"
          }
        }
      ]
    }
  },
  {
    $group: {
      _id: {
        "sectionType": "$sectionType"
      },
      "COUNT(*)": {
        $sum: 1
      }
    }
  },
  {
    $project: {
      "totalFailed": "$COUNT(*)",
      "sectionType": "$_id.sectionType",
      "_id": 0
    }
  },
  {
    "$lookup": {
      "from": "Departments",
      "let": {
        st: "$sectionType"
      },
      "pipeline": [
        {
          $match: {
            $expr: {
              $and: [
                {
                  $eq: [
                    "$sectionType",
                    "$st"
                  ]
                },
                {
                  $eq: [
                    "$section",
                    "A"
                  ]
                }
              ]
            }
          }
        },
        {
          $group: {
            _id: null,
            "COUNT(*)": {
              $sum: 1
            }
          }
        },
        {
          $project: {
            "totalCount": "$COUNT(*)",
            "_id": 0
          }
        }
      ],
      "as": "query2"
    }
  }
])

,这就是 mongo playground 供您参考。

You can use $lookup to perform your 2nd query. Simply put your 2nd query into the sub-pipeline

db.Departments.aggregate([
  {
    $match: {
      $and: [
        {
          "subject.failed": {
            $eq: "true"
          }
        },
        {
          "section": {
            $eq: "A"
          }
        }
      ]
    }
  },
  {
    $group: {
      _id: {
        "sectionType": "$sectionType"
      },
      "COUNT(*)": {
        $sum: 1
      }
    }
  },
  {
    $project: {
      "totalFailed": "$COUNT(*)",
      "sectionType": "$_id.sectionType",
      "_id": 0
    }
  },
  {
    "$lookup": {
      "from": "Departments",
      "let": {
        st: "$sectionType"
      },
      "pipeline": [
        {
          $match: {
            $expr: {
              $and: [
                {
                  $eq: [
                    "$sectionType",
                    "$st"
                  ]
                },
                {
                  $eq: [
                    "$section",
                    "A"
                  ]
                }
              ]
            }
          }
        },
        {
          $group: {
            _id: null,
            "COUNT(*)": {
              $sum: 1
            }
          }
        },
        {
          $project: {
            "totalCount": "$COUNT(*)",
            "_id": 0
          }
        }
      ],
      "as": "query2"
    }
  }
])

Here is the Mongo playground for your reference.

梦途 2025-02-14 19:51:44

您的要求并不是很清楚且难以猜测给定的样本。您可以简化$ MATD阶段。如果您运行mongoDB 5.0或从未运行,则可以使用

db.collection.aggregate([
  { $match: { section: "A" } },
  {
    $set: {
      failed: { $ifNull: [ { $first: "$subject.failed" }, "false" ] }
    }
  },
  {
    $setWindowFields: {
      partitionBy: {
        sectionType: "$sectionType",
        failed: "$failed"
      },
      output: {
        count_failed: { $sum: 1 }
      }
    }
  },
  {
    $setWindowFields: {
      partitionBy: "$sectionType",
      output: { count_total: { $sum: 1 } }
    }
  },
  { $match: { failed: "true" } },
  {
    $group: {
      _id: {
        sectionType: "$sectionType",
        totalCount: "$count_failed",
        totalFailed: "$count_total"
      }
    }
  }
])

mongo Playground

Your requirements are not really clear and difficult to guess with given sample. You can simplify the $match stage. If you run MongoDB 5.0 or never, you can use $setWindowFields

db.collection.aggregate([
  { $match: { section: "A" } },
  {
    $set: {
      failed: { $ifNull: [ { $first: "$subject.failed" }, "false" ] }
    }
  },
  {
    $setWindowFields: {
      partitionBy: {
        sectionType: "$sectionType",
        failed: "$failed"
      },
      output: {
        count_failed: { $sum: 1 }
      }
    }
  },
  {
    $setWindowFields: {
      partitionBy: "$sectionType",
      output: { count_total: { $sum: 1 } }
    }
  },
  { $match: { failed: "true" } },
  {
    $group: {
      _id: {
        sectionType: "$sectionType",
        totalCount: "$count_failed",
        totalFailed: "$count_total"
      }
    }
  }
])

Mongo Playground

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文