Mongodb - 汇总$ push如果有条件的话

Art*_*ias 12 mongodb mongodb-query mgo aggregation-framework

我正在尝试聚合一批文件.我想要推送的文件中有两个字段.但是,假设它们是"_id"和"A"字段,我只想要$ push"_id"和"A"如果"A"是$ gt 0.

我尝试了两种方法.

第一.

db.collection.aggregate([{
"$group":{
    "field": {
        "$push": {
            "$cond":[
                {"$gt":["$A", 0]},
                {"id": "$_id", "A":"$A"},
                null
            ]
        }
    },
    "secondField":{"$push":"$B"}
}])
Run Code Online (Sandbox Code Playgroud)

但这会将空值推到"字段",我不想要它.

第二个.

db.collection.aggregate([{
"$group":
    "field": {
        "$cond":[
            {"$gt",["$A", 0]},
            {"$push": {"id":"$_id", "A":"$A"}},
            null
        ]
    },
    "secondField":{"$push":"$B"}
}])
Run Code Online (Sandbox Code Playgroud)

第二个根本不起作用......

有没有办法在其他情况下跳过$ push?

添加:

预期文件:

{
    "_id":objectid(1),
    "A":2,
    "B":"One"
},
{
    "_id":objectid(2),
    "A":3,
    "B":"Two"
},
{
    "_id":objectid(3),
    "B":"Three"
}
Run Code Online (Sandbox Code Playgroud)

预期产出:

{
    "field":[
        {
            "A":"2",
            "_id":objectid(1)
        },
        {
            "A":"3",
            "_id":objectid(2)
        },
    ],
    "secondField":["One", "Two", "Three"]
}
Run Code Online (Sandbox Code Playgroud)

Ela*_*lem 25

您可以使用"$$REMOVE"

  • 这个系统变量是在 3.6 版中添加的(mongodb docs
db.collection.aggregate([{
   $group:{
       field: {
          $push: {
              $cond:[
                { $gt: ["$A", 0] },
                { id: "$_id", A:"$A" },
                "$$REMOVE"
            ]
          }
        },
        secondField:{ $push: "$B" }
    }
])
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您不必过滤空值。


Art*_*ias 10

在阅读@Veeram建议的帖子后,这是我对这个问题的回答

db.collection.aggregate([{
"$group":{
    "field": {
        "$push": {
            "$cond":[
                {"$gt":["$A", 0]},
                {"id": "$_id", "A":"$A"},
                null
            ]
        }
    },
    "secondField":{"$push":"$B"}
},
{
    "$project": {
        "A":{"$setDifferrence":["$A", [null]]},
        "B":"$B"
    }
}])
Run Code Online (Sandbox Code Playgroud)


Art*_*yom 8

另一种选择是使用 $filter 运算符:

db.collection.aggregate([
{ 
    $group : {
        _id: null,
        field: { $push: { id: "$_id", A : "$A"}},
        secondField:{ $push: "$B" }
    }
},
{
    $project: {
        field: {
            $filter: {
                input: "$field",
                as: "item",
                cond: { $gt: [ "$$item.A", 0 ] }
            }
        },
        secondField: "$secondField"
    }       
}])
Run Code Online (Sandbox Code Playgroud)

第一步,您组合数组并在第二步过滤它们