如何修复 MongoDB 聚合 $project $filter

Posted

技术标签:

【中文标题】如何修复 MongoDB 聚合 $project $filter【英文标题】:How to fix a MongoDB aggregate $project $filter 【发布时间】:2019-09-29 22:16:19 【问题描述】:

我的数据如下所示:


  "_id" : 1,
  "data" : [
    
      "id" : 1,
      "one" : [
        "user" : 2, "two" : 2,
        "user" : 1, "two" : 3
      ]
    
  ]


  "_id" : 2,
  "data" : [
    
      "id" : 2,
      "one" : [
        "user" : 2, "two" : 2,
        "user" : 1, "two" : 3
      ]
    
  ]

我想在一个聚合中进行过滤(因为上面的数据来自之前的阶段),以便过滤一个数组以仅显示用户等于 _id 的一个数组项。

以下返回一个空数组,如何让过滤器按我的预期填充一个数组?

db.parks.aggregate([$project: _id: 1, 'data.id': 1, 'data.one':
$filter: 
  input: '$data.one',
  as: 'un',
  cond: $eq: ['$$un.user', '$_id']
]).pretty()

这给出了:

 "_id" : 1, "data" : [  "id" : 1, "one" : [ ]  ] 
 "_id" : 2, "data" : [  "id" : 2, "one" : [ ]  ] 

将“$_id”替换为“$$un.user”会按预期显示所有 data.one 项,因此看起来问题出在 $eq 语句中。

如何让过滤器按预期显示一个数组?

【问题讨论】:

【参考方案1】:

你可以使用下面的聚合

db.collection.aggregate([
   "$project": 
    "data": 
      "$filter": 
        "input": 
          "$map": 
            "input": "$data",
            "in": 
              "id": "$$this.id",
              "one": 
                "$filter": 
                  "input": "$$this.one",
                  "as": "on",
                  "cond":  "$eq": ["$$on.user", "$_id"] 
                
              
            
          
        ,
        "as": "d",
        "cond":  "$eq": ["$$d.id", "$_id"] 
      
    
  
])

MongoPlayground

【讨论】:

行得通,你帮我找到了更好的解决方案:mongoplayground.net/p/VIDZW3iuYo9 - 不知道你可以在 $map 中使用 $$this $$this 指的是当前元素。因为我没有在$map 中使用as 表达式,如果你能看到这就是我使用$$this 的原因。

以上是关于如何修复 MongoDB 聚合 $project $filter的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 $project 中提供的 _id 与 mongodb 聚合进行 $match?

查询 $match 和 $project 重嵌套数据(MongoDB/聚合)

MongoDB——聚合管道之$project操作

MongoDB——聚合管道之$project操作

mongodb 聚合与 $project 有条件地排除一个字段

MongoDB 聚合中的多个 $project 阶段是不是会影响性能