Ответ 1
В современных выпусках (начиная с MongoDB 3.4) вы должны использовать $switch
, который в основном является аналогом ключевых слов switch
или case
в других языковых реализациях:
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 }
])
Это позволяет избежать вложения условий if..then..else
, что можно сделать с помощью $cond
и показано ниже. Но ниже все еще показан в качестве примера, что это всегда можно сделать, даже до того, как новый оператор даже явных ключевых слов if..then..else
, поскольку исходная запись массива всегда поддерживал этот синтаксис.
Отмечая также, что массив условий здесь, как правило, гораздо проще построить программно, чем создавать вложенную структуру данных для оператора, как это было необходимо с $cond
.
Ключевые слова if..then..else
для оператора $cond
являются лишь недавним дополнением к последним версиям MongoDB на момент написания (MongoDB 2.6 было введением ключевых слов. Фактический оператор был доступен с выпуском структуры агрегации в MongoDB 2.2). Намерение было для ясности, но в этом случае это, кажется, вызвало некоторую путаницу.
Поскольку оператор if..then.else
$cond
действительно является троичным оператором, так же, как это было бы реализовано во многих языках программирования. Это означает, что в качестве "встроенного" условия вместо создания "блоков" логики для условий все, что не соответствует первому условию, относится к else
.
Поэтому вы "вкладываете" утверждения, а не следите за блоками:
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 }
]);
Или даже с оригинальной нотацией массива, которую некоторые могут предпочесть при программном построении оператора:
db.items.aggregate([
{ "$project": {
"name": 1,
"customfield": {
"$cond": [
{ "$eq": [ "$field1", "4" ] },
30,
{ "$cond": [
{ "$eq": ["$field1","8"] },
25,
10
]}
]
}
}},
{ "$sort": { customfield: 1 }},
{ "$limit":12 }
]);
Тройной означает три условия, не больше, не меньше. Поэтому вся логика if..then..else
должна быть вложенной.