Warm tip: This article is reproduced from serverfault.com, please click

MongoDB-如何使用汇总来连续计算特定文档?

(MongoDB - How to count specific documents in a row using aggregation?)

发布于 2020-11-28 05:25:53

我要查询的集合如下所示:

[
  {
    "_id": {"$oid": "5fa8408978d1511e9b6ecee9"},
    "client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
    "date_created": {"$date": "2020-11-08T19:01:29.460Z"},
    "delivery_result_id": 0,
    "lead_id": {"$oid": "5fa84082c9ac031d0c4b6c01"}
  },
  {
    "_id": {"$oid": "5fa825495ee4001d2e0c2122"},
    "client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
    "date_created": {"$date": "2020-11-08T17:05:13.126Z"},
    "delivery_result_id": 0,
    "lead_id": {"$oid": "5fa82527c9ac031d0c4b6bfe"}
  },
  {
    "_id": {"$oid": "5fa825495ee4001d2e0c2121"},
    "client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
    "date_created": {"$date": "2020-11-08T17:05:13.125Z"},
    "delivery_result_id": 0,
    "lead_id": {"$oid": "5fa8251fc9ac031d0c4b6bfb"}
  },
  {
    "_id": {"$oid": "5fa825495ee4001d2e0c2120"},
    "client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
    "date_created": {"$date": "2020-11-08T17:05:13.125Z"},
    "delivery_result_id": 100,
    "lead_id": {"$oid": "5fa82516c9ac031d0c4b6bf8"}
  },
  {
    "_id": {"$oid": "5fa823e08b542d1d1c91d30e"},
    "client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
    "date_created": {"$date": "2020-11-08T16:59:12.362Z"},
    "delivery_result_id": 0,
    "lead_id": {"$oid": "5fa823d9c9ac031d0c4b6bf5"}
  },
  {
    "_id": {"$oid": "5fa823e08b542d1d1c91d30a"},
    "client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
    "date_created": {"$date": "2020-11-08T16:59:12.253Z"},
    "delivery_result_id": 0,
    "lead_id": {"$oid": "5fa823d3c9ac031d0c4b6bf2"}
  },
  {
    "_id": {"$oid": "5fa823e08b542d1d1c91d300"},
    "client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
    "date_created": {"$date": "2020-11-08T16:59:12.125Z"},
    "delivery_result_id": 100,
    "lead_id": {"$oid": "5fa823c1c9ac031d0c4b6bef"}
  },
  {
    "_id": {"$oid": "5fa823e08b542d1d1c91d2ff"},
    "client_id": {"$oid": "5f8d29a2beffbd2e00f81a54"},
    "date_created": {"$date": "2020-11-08T16:59:12.125Z"},
    "delivery_result_id": 100,
    "lead_id": {"$oid": "5fa823bac9ac031d0c4b6bec"}
  }
]

我想找出连续很多文件怎么会有delivery_result_id0 ,从最新文件开始我的查询必须包含一个截止日期,在这个截止日期之前我不会打扰。但是在我需要的日期之后出现的文档中,可以连续delivery_result_id使用0这是我的汇总:

db.lead_delivery_logs.aggregate([
        {
            $match: {
                client_id: ObjectId('5f8d29a2beffbd2e00f81a54'),
                date_created: {$gte: new Date("2020-11-07T16:59:12.362Z")}
            }
        },
        {
            $sort : {_id : -1}
        },
        {
            $match: {
                /* This is where I need to figure out that count */
            }
        },
    ])

因为我只需要计数,所以理想情况下,聚合将从3上面的集合中返回,因为有3个匹配delivery_result_id文档,0然后出现一个,100因此计数停止。

Questioner
codemonkey
Viewed
22
turivishal 2020-11-28 13:53:57

你可以试试,

  • $group按null并准备root所有文档的一个数组调用
  • $reduce迭代root数组循环并设置初始值结果数组和状态默认值0,检查条件是否delivery_result_id为0且初始值为true,然后用初始值连接对象,result否则设置状态false
  • $unwind 解构结果数组
  • $replaceRoot 替换为根结果对象
db.collection.aggregate([
  {
    $match: {
      client_id: ObjectId("5f8d29a2beffbd2e00f81a54"),
      date_created: { $gte: new Date("2020-11-07T16:59:12.362Z") }
    }
  },
  { $sort: { _id: -1 } },
  {
    $group: {
      _id: null,
      root: { $push: "$$ROOT" }
    }
  },
  {
    $project: {
      root: {
        $reduce: {
          input: "$root",
          initialValue: { result: [], status: true },
          in: {
            $cond: [
              {
                $and: [
                  { $eq: ["$$this.delivery_result_id", 0] },
                  { $eq: ["$$value.status", true] }
                ]
              },
              {
                result: { $concatArrays: ["$$value.result", ["$$this"]] },
                status: true
              },
              {
                result: "$$value.result",
                status: false
              }
            ]
          }
        }
      }
    }
  },
  { $unwind: "$root.result" },
  { $replaceRoot: { newRoot: "$root.result" } }
])

操场