无法从 $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 上试用。