使用1 $项目阶段

时间:2016-02-09 10:47:11

标签: mongodb aggregation-framework

考虑以下架构:

{ 
    "_id" : ObjectId("56b9bfb962debd68f8b61340"), 
    "Name" : "Parent", 
    "Children" : [
        {
            "Name" : "A", 
            "Age" : NumberInt(0)
        }, 
        {
            "Name" : "B", 
            "Age" : NumberInt(1)
        }, 
        {
            "Name" : "C", 
            "Age" : NumberInt(2)
        }
    ]
}

我正在使用2 $项目阶段。 1过滤"儿童"另一个选择字段除了" Children.Age":

db.collection.aggregate(
  [
    {
      $project: {
        Name: 1,
        Children: { $filter: {
          input: "$Children",
          as: "child",
          cond: { $gt: ["$$child.Age", 0] }
        } }
      }
    },
    {
      $project: {
        Name: 1,
        Children: { Name: 1 }
      }
    }
  ]
);

我可以只使用1 $项目阶段吗?

如果可能的话,我想避免使用$ unwind和$ group。

1 个答案:

答案 0 :(得分:1)

是的,您可以将管道缩短到一个阶段。为此,您需要使用$map运算符。

db.collection.aggregate([
    { "$project": { 
        "Name": 1, 
        "children": { 
            "$map": { 
                "input": { 
                    "$filter": { 
                        "input": "$Children", 
                        "as": "child", 
                        "cond": { "$gt": [ "$$child.Age", 0 ] } 
                    } 
                }, 
                "as": "ch", 
                "in": 
                "$$ch.Name" 
            } 
        } 
    }} 
])

另一种方法是使用$setDifference运算符和$map运算符运算符。但正如文档中所述:

  

$setDifference过滤掉其结果中的重复项,以输出仅包含唯一条目的数组。

db.collection.aggregate([
    { "$project": { 
        "Name": 1, 
        "Children": { 
            "$setDifference": [ 
                { "$map": { 
                    "input": "$Children", 
                    "as": "child", 
                    "in": { 
                        "$cond": [ 
                            { "$gt": [ "$$child.Age", 0 ] }, 
                            "$$child.Name", 
                            false 
                        ] 
                    } 
                }}, 
                [false]
            ] 
        }
    }}
])

返回:

{
        "_id" : ObjectId("56b9bfb962debd68f8b61340"),
        "Name" : "Parent",
        "Children" : [
                "B",
                "C"
        ]
}