如何在mongodb中的聚合期间有条件地投影字段 [英] How to conditionally project fields during aggregate in mongodb

查看:97
本文介绍了如何在mongodb中的聚合期间有条件地投影字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a user document like:

{
    _id: "s0m3Id",
    _skills: ["skill1", "skill2"],
}

现在我要放松通过 _skills 字段添加此文档,并为每个技能添加分数。所以我的总计看起来像这样:

Now I want to unwind this document by the _skills field and add a score for each skill. So my aggregate looks like:

{ 
  '$unwind': {'path': '$_skills', 'preserveNullAndEmptyArrays': true},
},
{
  '$project': {
    '_skills':
      'label': '$_skills',
      'skill_score': 1
    },
  }
},

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

Sometimes the _skills field can be empty, however in this case I still want the user document to flow through the aggregation - hence the preserveNullAndEmptyArrays parameter. However, the problem I'm having is that it will project a skill_score (though with no label) onto documents which had empty _skills array fields. Thus, when I go to $group the documents later on, those documents now have a non-empty _skills array, containing a single object, namely {skill_score: 1}. This is not what I want - I want documents which had empty (or non-existent) _skills fields to not have any skill_score projected onto them.

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

So how can I conditionally project a field based on the existence of another field? Using $exists does not help, because that is intended for querying, not for boolean expressions.

推荐答案

已更新

此聚合将设置的值如果 _skills 不存在,则skill_score 0 ,然后使用 $ redact 到删除具有 skill_score 等于 0 的子文档:

This aggregation will set the value of skill_score to 0 if _skills does not exist, then use $redact to remove the subdocument having skill_score equals to 0:

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'
      }
    }
  }
]);

结果如下:

[
  { "_id" : '', "_skills" : { "label" : "skill1", "skill_score" : 1 } },
  { "_id" : '', "_skills" : { "label" : "skill2", "skill_score" : 1 } },
  { "_id" : '' },
]

这篇关于如何在mongodb中的聚合期间有条件地投影字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆