首页 > 解决方案 > 具有 _id 关系的类型的最后一个值

问题描述

我有一个 Event 集合,其中包含一个type可以是01234和日期5的事件。createdAt每个事件都与另一个称为 RTS 的集合相关。

我想为每个 Rts 收集每种类型的最后一个事件。

使用我的解决方案的问题:

问题是,我必须types一一描述才能使其发挥作用。是否有任何解决方案可以通过type值诱导动态密钥创建?

这是我现在得到的:

  1. 我对数据进行排序
  2. Group byidRTS包含指向第二个集合的链接。对于每种类型,将值推送到特定数组中。
  3. 从类型数组中删除空值。
  4. 只保留第一个值(the most updated)
  5. 使数据可呈现。

[
  {
    $sort: {
      idRTS: -1,
      createdAt: -1
    }
  },
  {
    $group: {
      _id: '$idRTS',
      type0: {
        $push: {
          $cond: {
            if: {
              $eq: [
                '$type', 0
              ]
            },
            then: '$$ROOT',
            else: null
          }
        }
      },
      type5: {
        $push: {
          $cond: {
            if: {
              $eq: [
                '$type', 5
              ]
            },
            then: '$$ROOT',
            else: null
          }
        }
      }
    }
  },
  {
    $project: {
      _id: '$_id',
      type0: {
        '$filter': {
          'input': '$type0',
          'as': 'd',
          'cond': {
            '$ne': [
              '$$d', null
            ]
          }
        }
      },
      type5: {
        $filter: {
          input: '$type5',
          as: 'd',
          cond: {
            $ne: [
              '$$d', null
            ]
          }
        }
      }
    }
  },
  {
    $project: {
      _id: '$_id',
      type0: {
        $arrayElemAt: [
          '$type0', 0
        ]
      },
      type5: {
        '$arrayElemAt': [
          '$type5', 0
        ]
      }
    }
  }
]

标签: node.jsmongodbmongooseaggregate

解决方案


  • $match输入 0 或 5
  • $sort按降序idRTS排列createdAt
  • $group通过两者idRTScreatedAt字段并获取第一个对象,这将获得两种类型的第一个文档
  • $groupbyidRTS和 make 两种类型的数组,采用 k(key) 和 v(value) 格式
  • $project使用将type数组转换为对象$objectToArray
db.collection.aggregate([
  { $match: { type: { $in: [0, 5] } } },
  {
    $sort: {
      idRTS: -1,
      createdAt: -1
    }
  },
  {
    $group: {
      _id: {
        idRTS: "$idRTS",
        type: "$type"
      },
      type: { $first: "$$ROOT" }
    }
  },
  {
    $group: {
      _id: "$_id.idRTS",
      type: {
        $push: {
          k: { $toString: "$type.type" },
          v: "$type"
        }
      }
    }
  },
  { $project: { type: { $arrayToObject: "$type" } } }
])

操场


推荐阅读