MongoDB聚合,如何返回未受影响的项目

时间:2018-09-09 20:50:42

标签: mongodb aggregation-framework aggregation

我有一个集合,数据看起来像这样

{
    "fname":"bob",
    "lname":"jones",
    "role":"professional", 
    "active":true,
    "jobs":[{
        "job":"janitor",
        "current":true
    },{
        "job":"dog groomer"
        "current":false
    }]
}

我正在使用“聚合”来合并和剔除显示侧不需要的某些数据,并返回简化的对象数组。

People.aggregate([
  { "$match": { "role": "professional", "active": true }},
  { "$project": {
    "name": { "$concat": ["$fname", " ", "$lname"] },
    "jobs": {
      "$filter": {
        "input": "$jobs",
        "as": "job",
        "cond": { "$eq": ["$$job.current", true] }
      }
    }
  }},
  { "$project": { 
    "name": 1, 
    "job": { "$arrayElemAt": ["$jobs.job", 0] }
  }}
])

但是,我也想传递People对象中的其他项目。 是否需要通过整个管道传递它们? 如果我也将字段添加到第一个$ project中-那么只有其中一个会回来...

所以现在

People.aggregate([
  { "$match": { "role": "professional", "active": true }},
  { "$project": {
    "name": { "$concat": ["$fname", " ", "$lname"] },
    "jobs": {
      "$filter": {
        "input": "$jobs",
        "as": "job",
        "cond": { "$eq": ["$$job.current", true] }
      }
    },
    "role":"$role",
    "active":"$active"
  }},
  { "$project": { 
    "name": 1, 
    "job": { "$arrayElemAt": ["$jobs.job", 0] },
    "role":"$role",
    "active":"$active"
  }}
])

给我:

name 
job 
role

我想念什么?

1 个答案:

答案 0 :(得分:1)

使用$addFields代替$project,并排除使用$project删除lname和fname字段。

类似

People.aggregate([
  {"$match":{"role":"professional","active":true}},
  {"$addFields":{
    "name":{"$concat":["$fname"," ","$lname"]},
    "job":{
      "$let":{
        "vars":{
          "jobs":{
            "$arrayElemAt":[
              {"$filter":{
                "input":"$jobs",
                "cond":{"$eq":["$$this.current",true]}
              }},
              0
            ]
          }
        },
        "in":"$$jobs.job"
      }
    }
  }},
  {"$project":{"fname":0,"lname":0}}
])