无法从 $match 与 $and 在 pymongo 中获得结果
Unable to get result from $match with $and in pymongo
我有 mongodb 个查询,我正在尝试用 pymongo 实现它。
我有以下合集词典:
{'_id': 0,
'name': 'aimee Zank',
'scores': [{'score': 10.463179736705023, 'type': 'exam'},
{'score': 11.78273309957772, 'type': 'quiz'},
{'score': 75.8740349954354, 'type': 'homework'}]}
{'_id': 1,
'name': 'Tomas Jude',
'scores': [{'score': 55.9736705023, 'type': 'exam'},
{'score': 50.78273309957772, 'type': 'quiz'},
{'score': 45.8740349954354, 'type': 'homework'}]}
我正在尝试查询在所有三种类型(考试、测验和家庭作业)中得分都高于 40 的学生。为此,我在聚合中使用 $match 和 $and 。我无法得到任何结果,$或条件正常。
agg_result=Collection.aggregate([
{"$unwind" : "$scores" },
{"$match": {"scores.score": {"$gt":40}}},
{
"$match": {
"$and" : [
{"scores.type": "exam"},
{"scores.type":"homework"}
]
}
},
{
"$group": {
"_id" : "$_id",
"name": {"$first": "$name"},
"scores":{"$push" : "$scores"}
}
},
{
"$sort": {
"_id" : 1
}
}
])
使用$or,结果显示为,
{'_id': 0,
'name': 'aimee Zank',
'scores': [{'score': 75.8740349954354, 'type': 'homework'}]}
{'_id': 1,
'name': 'Tomas Jude',
'scores': [{'score': 55.9736705023, 'type': 'exam'},
{'score': 45.8740349954354, 'type': 'homework'}]}
如何解决 $and 问题?
我可能小题大做了,但这是第一个想到的(这意味着可能有更好的方法)。您可以使用 "$map"
循环遍历 scores
数组,我们可以在其中使用 type
检查 score
并构建 pass
数组。
db.collection.aggregate([
{
// create array of pass status
"$set": {
"pass": {
"$map": {
"input": "$scores",
"as": "score",
"in": {
"$switch": {
"branches": [
{
"case": { "$eq": [ "$$score.type", "exam" ] },
"then": { "exam": { "$gt": [ "$$score.score", 40 ] } }
},
{
"case": { "$eq": [ "$$score.type", "quiz" ] },
"then": { "quiz": { "$gt": [ "$$score.score", 40 ] } }
},
{
"case": { "$eq": [ "$$score.type", "homework" ] },
"then": { "homework": { "$gt": [ "$$score.score", 40 ] } }
}
],
"default": "$$score"
}
}
}
}
}
},
{
"$match": {
"pass.exam": true,
"pass.quiz": true,
"pass.homework": true
}
},
// uncomment to "$unset" "pass"
// {
// "$unset": "pass"
// }
])
在 mongoplayground.net 上试用。
我有 mongodb 个查询,我正在尝试用 pymongo 实现它。
我有以下合集词典:
{'_id': 0,
'name': 'aimee Zank',
'scores': [{'score': 10.463179736705023, 'type': 'exam'},
{'score': 11.78273309957772, 'type': 'quiz'},
{'score': 75.8740349954354, 'type': 'homework'}]}
{'_id': 1,
'name': 'Tomas Jude',
'scores': [{'score': 55.9736705023, 'type': 'exam'},
{'score': 50.78273309957772, 'type': 'quiz'},
{'score': 45.8740349954354, 'type': 'homework'}]}
我正在尝试查询在所有三种类型(考试、测验和家庭作业)中得分都高于 40 的学生。为此,我在聚合中使用 $match 和 $and 。我无法得到任何结果,$或条件正常。
agg_result=Collection.aggregate([
{"$unwind" : "$scores" },
{"$match": {"scores.score": {"$gt":40}}},
{
"$match": {
"$and" : [
{"scores.type": "exam"},
{"scores.type":"homework"}
]
}
},
{
"$group": {
"_id" : "$_id",
"name": {"$first": "$name"},
"scores":{"$push" : "$scores"}
}
},
{
"$sort": {
"_id" : 1
}
}
])
使用$or,结果显示为,
{'_id': 0,
'name': 'aimee Zank',
'scores': [{'score': 75.8740349954354, 'type': 'homework'}]}
{'_id': 1,
'name': 'Tomas Jude',
'scores': [{'score': 55.9736705023, 'type': 'exam'},
{'score': 45.8740349954354, 'type': 'homework'}]}
如何解决 $and 问题?
我可能小题大做了,但这是第一个想到的(这意味着可能有更好的方法)。您可以使用 "$map"
循环遍历 scores
数组,我们可以在其中使用 type
检查 score
并构建 pass
数组。
db.collection.aggregate([
{
// create array of pass status
"$set": {
"pass": {
"$map": {
"input": "$scores",
"as": "score",
"in": {
"$switch": {
"branches": [
{
"case": { "$eq": [ "$$score.type", "exam" ] },
"then": { "exam": { "$gt": [ "$$score.score", 40 ] } }
},
{
"case": { "$eq": [ "$$score.type", "quiz" ] },
"then": { "quiz": { "$gt": [ "$$score.score", 40 ] } }
},
{
"case": { "$eq": [ "$$score.type", "homework" ] },
"then": { "homework": { "$gt": [ "$$score.score", 40 ] } }
}
],
"default": "$$score"
}
}
}
}
}
},
{
"$match": {
"pass.exam": true,
"pass.quiz": true,
"pass.homework": true
}
},
// uncomment to "$unset" "pass"
// {
// "$unset": "pass"
// }
])
在 mongoplayground.net 上试用。