MongoDB 文档中文档的聚合过滤器

MongoDB Aggregation filter on documents within documents

你能帮我解决一个问题吗... 我有这个 json 但我只想 return 节点。

{
   "_id":{
      "userArea":NumberInt(4927)
   },
   "pages":{
      "12":{
         "page":NumberInt(2635), 
         "progress":"COMPLETED",
         "progressType":"USER_PROGRESS",
         "end":11
      },
      "13":{
         "page":NumberInt(2627),
         "progress":"COMPLETED",
         "progressType":"USER_PROGRESS",
         "end":ISODate("2018-04-19T15:04:29.000+0000")
      }
      "14":{
         "page":NumberInt(2627),
         "progress":"CANCELLED",
         "progressType":"USER_PROGRESS",
         "end":ISODate("2018-04-19T15:04:29.000+0000")
      }
   }
}

这样....没有header

      "12":{
         "page":NumberInt(2635), 
         "progress":"COMPLETED",
         "progressType":"USER_PROGRESS",
         "end":11
      },
      "13":{
         "page":NumberInt(2627),
         "progress":"COMPLETED",
         "progressType":"USER_PROGRESS",
         "end":ISODate("2018-04-19T15:04:29.000+0000")
      }

你能帮帮我吗?我只需要过滤已完成的!!!

您可以使用此聚合查询:

  • 首先使用$objectToArray生成一个数组,可以使用值v过滤值。这是在 input.
  • 中完成的
  • 然后使用该输入值,您可以过滤 progress 值不是 CANCELLED 的元素。并使用 $arrayToObject
  • 再次转换为 object
db.collection.aggregate([
  {
    "$project": {
      "pages": {
        "$arrayToObject": {
          "$filter": {
            "input": {
              "$objectToArray": "$pages"
            },
            "cond": {
              "$ne": [
                "$$this.v.progress",
                "CANCELLED"
              ]
            }
          }
        }
      }
    }
  }
])

示例here

抱歉,我第一次尝试时读到“without header”,我以为你想使用 $replaceRoot 但我认为这个新查询就是你想要的(也避免了 $unwind ).

但我认为你说“without hedaer”是为了显示问题中简化的输出。此外,如果您无法输出 header,只需使用 $replaceRoot 添加一个新阶段。示例 here

您需要像 here

那样执行许多管道
db.collection.aggregate([
  {
    "$project": {
      "p": {
        "$objectToArray": "$pages"
      }
    }
  },
  {
    "$unwind": "$p"
  },
  {
    "$match": {
      "p.v.progress": "COMPLETED"
    }
  },
  {
    "$group": {
      "_id": "$_id",
      "p": {
        "$addToSet": "$p"
      }
    }
  },
  {
    $project: {
      "a": {
        "$arrayToObject": "$p"
      }
    }
  },
  {
    "$replaceRoot": {
      "newRoot": "$a"
    }
  }
])
  1. 调整形状以便您可以应用滤镜。
  2. 再次分组以返回到您的原始架构。否则,您可以在 $match 管道停止。

如果可能,请更改架构,不要使用动态键。