我的MongoDB版本是3.6.3
我收藏的一个例子:
/*A snippet of my collection*/
/* 1 */
{
"_id" : ObjectId("5a81a0de19a4ea2a8b119baa"),
"Site" : 123,
"Event" : "AnEvent",
"SubEvent" : "MoreDetails",
"Level" : 2
}
/* 2 */
{
"_id" : ObjectId("5a81a0de19a4ea2a8b119bab"),
"Site" : 456,
"Event" : "TheEvent",
"SubEvent" : "FurtherDetails",
"Level" : 3
}
/* 3 */
{
"_id" : ObjectId("5a81a0de19a4ea2a8b119bac"),
"Site" : 789,
"Event" : "WorldEndingEvent",
"SubEvent" : "RelevantDetails",
"Level" : 5
}
我正在尝试输出以下文档(根据Event和SubEvent字段有条件地添加新字段):
/*Desired output of query*/
/* 1 */
{
"_id" : ObjectId("5a81a0de19a4ea2a8b119baa"),
"Site" : 123,
"Event" : "AnEvent",
"SubEvent" : "MoreDetails",
"Level" : 2,
"NewLevel": 1
}
/* 2 */
{
"_id" : ObjectId("5a81a0de19a4ea2a8b119bab"),
"Site" : 456,
"Event" : "TheEvent",
"SubEvent" : "FurtherDetails",
"Level" : 3,
"NewLevel": 2
}
/* 3 */
{
"_id" : ObjectId("5a81a0de19a4ea2a8b119bac"),
"Site" : 789,
"Event" : "WorldEndingEvent",
"SubEvent" : "RelevantDetails",
"Level" : 5,
"NewLevel": 4
}
为实现这一目标,我使用的是MongoDB提供的switch case结构(但没有成功):
/*This does not work as Mongo does not recognize $Event in case statement*/
db.getCollection('Error_events_aggregated').aggregate([
{
$project: {
Site: 1,
Event: 1,
SubEvent: 1,
Level: 1,
NewLevel: {
$switch: {
branches: [
{
case: {$and: [
{"$Event": {$eq: "AnEvent"}},
{"$SubEvent": {$eq: "MoreDetails"}}
]},
then: 1
},
{
case: {$and: [
{"$Event": {$eq: "TheEvent"}},
{"$SubEvent": {$eq: "FurtherDetails"}}
]},
then: 2
},
{
case: {$and: [
{"$Event": {$eq: "WorldEndingEvent"}},
{"$SubEvent": {$eq: "RelevantDetails"}}
]},
then: 4
}
],
default: "$Level"
}
}
}
}
])
这不起作用,因为MongoDB无法识别$ Event。
但是,如果我使用类似的方法(基于开关案例的投影)但使用$ gt(和类似的)运算符,那么MongoDB在识别$ Event时没有任何问题......
/*This works. Mongo recognizes $Event now, inside the case statement*/
db.getCollection('Error_events_aggregated').aggregate([
{
$project: {
Site: 1,
Event: 1,
SubEvent: 1,
Level: 1,
NewLevel: {
$switch: {
branches: [
{
case: {$gt: ["$Event", "V"]}, /*Matches WorldEndingEvent*/
then: 4
},
{
case: {$gt: ["$Event", "S"]}, /*Matches TheEvent*/
then: 2
},
{
case: {$gt: ["$Event", "Am"]}, /*Matches AnEvent*/
then: 1
}
],
default: "$Level"
}
}
}
}
])
有人可以帮我弄清楚我做错了什么吗?我尝试阅读文档,但所有与$ switch和$ cond相关的示例仅涵盖$ gt和类似的运算符,并不涵盖基于平等的操作。
我尝试使用{:}语法来检查相等性,但无济于事。
答案 0 :(得分:3)
您可以使用$addFields代替$project
。 $switch
与$eq
的语法在这里完全不同,请尝试:
db.col.aggregate([
{
$addFields: {
NewLevel: {
$switch: {
branches: [
{
case: {
$and: [
{ $eq: [ "$Event", "AnEvent" ] },
{ $eq: [ "$SubEvent", "MoreDetails" ] }
]
},
then: 1
},
{
case: {
$and: [
{ $eq: [ "$Event", "TheEvent" ] },
{ $eq: [ "$SubEvent", "FurtherDetails" ] }
]
},
then: 2
},
{
case: {
$and: [
{ $eq: [ "$Event", "WorldEndingEvent" ] },
{ $eq: [ "$SubEvent", "RelevantDetails" ] }
]
},
then: 4
}
],
default: "$Level"
}
}
}
}
])
答案 1 :(得分:2)
mongoDB中的switch语句基本上是对一系列案例EXPRESSIONS进行评估,因此case语句中包含的任何内容都应该是一个表达式,而不仅仅是变量名。是的,我们可以使用$ eq(mongDB中的Equal运算符)而不是$ gt < / p>
db.getCollection('Error_events_aggregated').aggregate([
{
$project: {
Site: 1,
Event: 1,
SubEvent: 1,
Level: 1,
NewLevel: {
$switch: {
branches: [
{
case: {$eq: ["$Event", "WorldEndingEvent"]}, /*Matches WorldEndingEvent*/
then: 4
},
{
case: {$eq: ["$Event", "TheEvent"]}, /*Matches TheEvent*/
then: 2
},
{
case: {$eq: ["$Event", "AnEvent"]}, /*Matches AnEvent*/
then: 1
}
],
default: "$Level"
}
}
}
}
])
如果此工作正常并且有任何其他更改,请告诉我。