mongodb在$ filter中使用投影

Fai*_*eef 2 mongodb mongodb-query

我已插入样本文件

db.test.insert({
    x:1, 
    a:[
        {b:1,c:1,d:1},
        {b:2,c:2}
      ]
})
Run Code Online (Sandbox Code Playgroud)

我在尝试使用$ fitler聚合时遇到以下2个问题,如下所示

db.test.aggregate(
{$project:{ 
  a:{$filter:{
    input : '$a',
    as : 'item',
    cond : '$$item.d'
  }}
}}
)
Run Code Online (Sandbox Code Playgroud)

元素存在

1]如何测试元素广告的存在,我找到了一种只使用cond的方法:'$$ item.d',但是我认为应该有一个更好的方法。

选择性投影

2]如何有选择地投影b和d节点。我尝试了下面的代码,它可以工作,但我认为投影中也有一个管道。因此,我在同一节点上两次应用了投影1用于过滤数组元素,2用于数组元素节点

db.test.aggregate(
{$project:{ 
  a:{$filter:{
    input : '$a',
    as : 'item',
    cond : '$$item.d'
  }},
  a:{b:1, d:1}
}}
)
Run Code Online (Sandbox Code Playgroud)

我似乎找到了解决方案,但我认为可能会有更好的方法。谢谢你的答复!

小智 5

(1)在我看来,$ exists运算符在聚合管道中尚不可用。您可能希望检查是否有要求它的吉拉车,如果有,请观看并投票,如果没有,请添加一个?

我相信,您的解决方法将仅返回item.d为true的情况,而不会返回它存在的情况。因此,如果item.d == null,false,0,则不会返回。我建议尝试这样:

cond : { $gte : [ '$$item.d', null ] }
Run Code Online (Sandbox Code Playgroud)

(2)我不是100%肯定我理解这个问题,但是如果我明白了,我认为解决方法是在管道中有两个$ project。所以像这样:

db.test.aggregate( 
 [ { $project:
     {a:{$filter:{input:'$a',as:'item',cond:{$gte:['$$item.d',null]}}}}
   },
   { $project: { a : { b : 1, d : 1 } } }
 ]
)
Run Code Online (Sandbox Code Playgroud)