我知道这里有这个问题的其他版本,但我正在努力让这个问题保持一致.我有类似以下内容的文档:

[
{_id: 1, date: "2022-04-08T23:30:12.000Z", books: [{author: "Johnson", title: "First Title"}, {author: "Smith", title: "Second Title}]},
{_id: 2, date: "2022-04-22T23:30:12.000Z", books: [{author: "Johnson", title: "Some Other Title"}]},
{_id: 3, date: "2022-05-05T23:30:12.000Z", books: [{author: "Smith", title: "Title Round 2"}]},
{_id: 4, date: "2022-05-15T23:30:12.000Z", books: [{author: "Johnson", title: "Found a Title", {author: "Smith", title: "Wrote again"}, {author: "Brooks", title: "New Title"}]}
]

我try 按月-年对文档进行分组,然后计算不同值显示在作者字段上的次数.到目前为止,我有一个管道,看起来像:

{
          "$unwind": "$books"
        },
        {
          $project: {
            _id: 1,
            books: 1,
            month: {
              "$month": "$date"
            },
            year: {
              "$year": "$date"
            }
          }
        },
        {
          $project: {
            _id: 1,
            books: 1,
            date: {
              $concat: [
                {
                  $substr: [
                    "$year",
                    0,
                    4
                  ]
                },
                "-",
                {
                  $substr: [
                    "$month",
                    0,
                    2
                  ]
                },
                
              ]
            }
          }
        },
        {
          $group: {
            _id: {
              date: "$date",
              books: {
                freq: {
                  $sum: 1
                }
              }
            }
          }
        },
        {
          $project: {
            "_id": 1,
            "date": 1,
            "books": 1
          }
        },
        
      ]
    }

我的目标是最终输出如下所示:

[
{date: "2022-04", authors: { "Johnson": 2, "Smith": 1}},
{date: "2022-05", authors: {"Johnson": 1, "Smith": 2, "Brooks": 1}}
]

我已经找到了对子文档运行计数的方法,但在try 实现时,我正在丢失按日期分组的方法,或者只是得到错误.我已经看得够多了,知道它是可行的,只是在试图把它做得恰到好处时迷失了方向.如有任何帮助,我们不胜感激.

推荐答案

您的前3个阶段可以保持不变(假设日期存储为Date对象而不是字符串)

在那之后

  1. $date$books.author字段分组,并计算每组的出现次数.这将给出您在最终答案中需要的计数
  2. 然后仅按$date分组,并将每个计数以键值{k:key,v:value}的格式推送到authors数组,以便可以在下一阶段将其转换为对象
  3. authors数组上的$arrayToObject,以将其转换为对象

如果您还想对日期进行排序,则添加一个{ $sort: {date: 1 } }阶段

db.collection.aggregate([
  { $unwind: "$books" },
  { $project: { _id: 1, books: 1, month: { "$month": "$date" }, year: { "$year": "$date" } } },
  { $project: { _id: 1, books: 1, date: { $concat: [ { $substr: [ "$year", 0, 4 ] }, "-", { $substr: [ "$month", 0, 2 ] } ] } } },
  {
    $group: {
      _id: { date: "$date", author: "$books.author" },
      count: { $sum: 1 }
    }
  },
  {
    $group: {
      _id: "$_id.date",
      authors: { $push: { k: "$_id.author", v: "$count" } }
    }
  },
  {
    $project: {
      _id: 0,
      date: "$_id",
      authors: { $arrayToObject: "$authors" }
    }
  }
])

playground您可以从顶部的Stage下拉列表中查看中间结果

Mongodb相关问答推荐

在mongdob中按子文档筛选不起作用

从 MongoDB 中的聚合结果中获取不同的值

判断对象数组中的值是否存在golang

使用名为 Object 键的 uuid 创建 mongodb 文档

创建索引需要很长时间

为什么使用整数作为 pymongo 的键不起作用?

使用 Spring Boot >= 2.0.1.RELEASE 将 ZonedDateTime 保存到 MongoDB 时出现 CodecConfigurationException

如何构建我只需要打开一次 mongodb 连接的快速应用程序?

什么是 Mongoose (Nodejs) 复数规则?

mongodb上不区分大小写的查询

如何在 mongodb 本机驱动程序中对 find() 进行字段 Select ?

Clojure 和 NoSQL 数据库

启动mongodb和express的正确方法?

在 MongoDB 中按条件分组

使用 mongoimport 将日期(ISODate)导入 MongoDB

如何为 node.js 中的 MongoDB 索引指定 javascript 对象中的属性顺序?

Mongoose 版本控制:when is it safe to disable it?

Mongoose:查询starts with

MongoDb:聚合 $lookup 过滤外部文档

聚合 $lookup 匹配管道中文档的总大小超过最大文档大小