如何在mongodb中的聚合期间有条件地投影字段

rma*_*een 2 mongodb aggregation-framework

我有一个用户文档,例如:

{
    _id: "s0m3Id",
    _skills: ["skill1", "skill2"],
}
Run Code Online (Sandbox Code Playgroud)

现在,我想按_skills领域展开本文档,并为每种技能添加一个分数。所以我的聚合看起来像:

{ 
  '$unwind': {'path': '$_skills', 'preserveNullAndEmptyArrays': true},
},
{
  '$project': {
    '_skills':
      'label': '$_skills',
      'skill_score': 1
    },
  }
},
Run Code Online (Sandbox Code Playgroud)

有时该_skills字段可以为空,但是在这种情况下,我仍然希望用户文档流经聚合-因此是preserveNullAndEmptyArrays参数。但是,我遇到的问题是,它将skill_score(具有no label)投影到具有空_skills数组字段的文档上。因此,当我$group稍后浏览文档时,这些文档现在具有一个非空_skills数组,其中包含一个对象,即{skill_score: 1}。这不是我想要的-我希望具有空(或不存在)_skills字段的文档没有任何Skill_score投影到它们上。

那么,如何根据另一个字段的存在条件有条件地投影一个字段?使用$exists无济于事,因为它只用于查询,而不用于布尔表达式。

kkk*_*kkk 5

更新

如果不存在,则此聚合将设置skill_scoreto 的值,然后用于删除等于的子文档:0_skills$redactskill_score0

db.project_if.aggregate([
  {
    $unwind: {
      path: '$_skills',
      preserveNullAndEmptyArrays: true,
    }
  },
  {
    $project: {
      _skills: {
        label: '$_skills',
        skill_score: {
          $cond: {
            if: {
              $eq: ['$_skills', undefined]
            },
            then: 0,
            else: 1,
          }
        }
      }
    }
  }, 
  {
    $redact: {
      $cond: {
        if: { $eq: [ "$skill_score", 0 ] },
        then: '$$PRUNE',
        else: '$$DESCEND'
      }
    }
  }
]);
Run Code Online (Sandbox Code Playgroud)

结果将是:

[
  { "_id" : '', "_skills" : { "label" : "skill1", "skill_score" : 1 } },
  { "_id" : '', "_skills" : { "label" : "skill2", "skill_score" : 1 } },
  { "_id" : '' },
]
Run Code Online (Sandbox Code Playgroud)