如何在mongodb中的聚合期间有条件地投影字段 [英] How to conditionally project fields during aggregate in 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屋!