在聚合时 MongoDB 中是否有其他的东西到 $cond
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27479347/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there an elseif thing in MongoDB to $cond while aggregating
提问by humblerookie
So I need a custom field calculated in MongoDB as follows
所以我需要一个在MongoDB中计算的自定义字段如下
if( field1 =="A") ->customfield=10
else if(field1 =="B" )->customfield=20
else (field1 =="C" ) ->customfield=15
I'm using aggregation along with the $project statement. But the $cond operator doesn't allow elseif (subbranching the else) and merely allows two static branches if and else. Using a nested elseif causes
我将聚合与 $project 语句一起使用。但是 $cond 操作符不允许 elseif (子分支 else)并且只允许两个静态分支 if 和 else。使用嵌套的 elseif 导致
"exception: field inclusion is not allowed inside of $expressions"
"exception: field inclusion is not allowed inside of $expressions"
Heres my query(which gives me the error)
这是我的查询(这给了我错误)
db.items.aggregate([ { $project :
{
name: 1,
customfield:
{
$cond: { if: { $eq: [ "$field1", "4" ] }, then: 30,
else: {
if:
{ $eq: ["$field1","8"]},
then: 25, else: 10}}
}
}},{ $sort: { customfield: 1 }},{$limit:12}]);
Is there a method or workaround to this. My apologies if this is a repeated question but I wasn't able to find a similar one.
有没有方法或解决方法。如果这是一个重复的问题,我很抱歉,但我找不到类似的问题。
回答by Neil Lunn
With modern releases ( since MongoDB 3.4 ) you would use $switch
, which is basically the counterpart to switch
or case
keywords in other language implementations:
对于现代版本(自 MongoDB 3.4 起),您将使用$switch
,它基本上是其他语言实现中的switch
orcase
关键字的对应物:
db.items.aggregate([
{ "$project": {
"name": 1,
"customfield": {
"$switch": {
"branches": [
{ "case": { "$eq": [ "$field1", "4" ] }, "then": 30 },
{ "case": { "$eq": [ "$field1", "8" ] }, "then": 25 }
],
"default": 10
}
}
}},
{ "$sort": { customfield: 1 }},
{ "$limit":12 }
])
This avoids nestingthe if..then..else
conditions as can be done using $cond
and shown below. But the below still shows as an example that this could always be done, even before the new operator of even the explicit if..then..else
keywords since the original array notation always maintained that syntax.
这避免嵌套的if..then..else
作为是可以做到用条件$cond
和如下所示。但下面仍然作为一个例子表明,即使在显式if..then..else
关键字的 new 运算符之前,也可以始终这样做,因为原始数组表示法始终保持该语法。
Noting also that an arrayof conditions here is typically also a lot easier to construct programatically than creating a nesteddata structure for the statement as was needed with $cond
.
还注意到,一个阵列的条件下在这里通常也比创建一个更容易编程构造嵌套的语句的数据结构与需要$cond
。
The if..then..else
keywords to the $cond
operator are only a recent addition as of recent versions of MongoDB at the time of writing ( MongoDB 2.6 was the introduction of the keywords. The actual operator was available with release of the aggregation framework in MongoDB 2.2 ). The intention was for clarity but in this case it seems to has caused some confusion.
运算符的if..then..else
关键字$cond
只是在撰写本文时最近版本的 MongoDB 中最近添加的(MongoDB 2.6 是关键字的引入。实际的运算符在 MongoDB 2.2 中的聚合框架发布时可用)。目的是为了清楚起见,但在这种情况下,它似乎引起了一些混乱。
As an if..then.else
operator $cond
is indeed a ternaryoperator, just as would be implemented in many programming languages. This means as an "inline" conditional, rather than creating "blocks" of logic to the conditions, anything that does not meet the first condition belongs under else
.
由于if..then.else
运算符$cond
确实是三元运算符,就像在许多编程语言中实现的一样。这意味着作为“内联”条件,而不是为条件创建逻辑“块”,任何不满足第一个条件的都属于else
.
Therefore you "nest" the statements rather than follow blocks:
因此,您“嵌套”语句而不是遵循块:
db.items.aggregate([
{ "$project": {
"name": 1,
"customfield": {
"$cond": {
"if": { "$eq": [ "$field1", "4" ] },
"then": 30,
"else": {
"$cond": {
"if": { "$eq": ["$field1","8"]},
"then": 25,
"else": 10
}
}
}
}
}},
{ "$sort": { customfield: 1 }},
{ "$limit":12 }
]);
Or even with the original arraynotation, which some might prefer if building the statement programatically:
或者甚至使用原始数组表示法,如果以编程方式构建语句,有些人可能更喜欢:
db.items.aggregate([
{ "$project": {
"name": 1,
"customfield": {
"$cond": [
{ "$eq": [ "$field1", "4" ] },
30,
{ "$cond": [
{ "$eq": ["$field1","8"] },
25,
10
]}
]
}
}},
{ "$sort": { customfield: 1 }},
{ "$limit":12 }
]);
Ternary means three conditions, no more no less. So all if..then..else
logic must be nested.
三元意味着三个条件,不多不少。所以所有的if..then..else
逻辑都必须嵌套。
回答by nort
MongoDB 3.4 has a new thing called $switch
for this exact thing!
MongoDB 3.4 有一个新东西叫做$switch
这个确切的东西!
$switch: {
branches: [
{ case: <expression>, then: <expression> },
{ case: <expression>, then: <expression> },
...
],
default: <expression>
}
https://docs.mongodb.com/manual/reference/operator/aggregation/switch/
https://docs.mongodb.com/manual/reference/operator/aggregation/switch/
回答by KARNAV PARGI
if you are using only object then
如果您只使用对象,那么
{
$cond: {
$and: [
{ if: { $eq: ["$$field1", 'A'] }, then: '10', else: 15 },
{ if: { $eq: ["$$field1", 'B'] }, then: '20', else: 15 },
{ if: { $eq: ["$$field1", 'C'] }, then: '10', else: 15 },
]
}
}
And if you are Using Array find Data
如果您使用数组查找数据
{
$map: {
input: "$fields", as: "field1", in: {
$cond: {
$and: [
{ if: { $eq: ["$$field1", 'A'] }, then: '10', else: 15 },
{ if: { $eq: ["$$field1", 'B'] }, then: '20', else: 15 },
{ if: { $eq: ["$$field1", 'C'] }, then: '10', else: 15 },
]
}
}
}
}