猫鼬 - 如何查询对象数组的最后一个对象中的字段

Mongoose - How to query field in the last object of an array of objects

我有 MongoDB 文档结构如下:

{
    "_id": "5d8b987f9f8b9f9c8c8b9f9",
    "targetsList": [
        {
            "target": "user",
            "statusList": [
                {
                    "date": "2018-01-01",
                    "type": "OK"
                },
                {
                    "date": "2018-01-02",
                    "type": "FAILD"
                }
            ]
        }
    ]
}

而且我想计算在 "targetList" 数组中的所有文档,其中有一个对象 "target"=="user" - 并且该对象包含在其 "statusList" 数组的 last 元素上,一个具有 " 类型的对象" != "失败".

关于如何实现这种查询有什么想法吗?

Mongo游乐场: https://mongoplayground.net/p/3bCoHRnh-KQ 在这个例子中,我期望计数为1,因为只有第二个对象符合条件。

除非元素是最后一个索引是至关重要的,否则这应该适用于您的情况。

db.collection.find({
  "targetsList.statusList.type": {
    $in: [
      "FAILD"
    ]
  }
})

这将检索 type 值为 FAILD 的文档。要反转它,您可以将 $in 换成 $nin

已更新 playground here

聚合管道
第一步 - 过滤掉"targetsList.target": "user"
第二步 - $unwind targetsList 将其从数组中取出
第三步 - 使用$arrayElemAt
获取targetsList.statusList数组的最后一个元素 第 4 步 - 获取最后一个元素不失败的结果
第 5 步 - 计数

demo - 您可以尝试删除部分管道以查看中间结果是什么

db.collection.aggregate([
  {
    $match: {
      "targetsList.target": "user"
    }
  },
  {
    $unwind: "$targetsList"
  },
  {
    $project: {
      "targetsList.statusList": {
        $arrayElemAt: [
          "$targetsList.statusList",
          -1
        ]
      },
      
    }
  },
  {
    $match: {
      "targetsList.statusList.type": {
        $ne: "FAILD"
      }
    }
  },
  {
    $count: "withoutFailedInLastElemCount"
  }
])

这里有另一种方法可以使用领先的怪物“$match”。

db.collection.aggregate([
  {
    "$match": {
      "targetsList.target": "user",
      "$expr": {
        "$reduce": {
          "input": "$targetsList",
          "initialValue": false,
          "in": {
            "$or": [
              "$$value",
              {
                "$ne": [
                  {
                    "$last": "$$this.statusList.type"
                  },
                  "FAILD"
                ]
              }
            ]
          }
        }
      }
    }
  },
  {
    "$count": "noFailedLastCount"
  }
])

mongoplayground.net 上试用。