mongodb使用单个数组元素匹配所有条件

mongodb使用单个数组元素匹配所有条件,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有一系列这样的测试 { "tests" : [ { "testId" : "1", "details" : { "status" : "Completed" } }, { "testId" : "2", "details" : { "status" :

我有一系列这样的测试

{

    "tests" : [

        {
            "testId" : "1",
            "details" : {
                "status" : "Completed"
            }
        },
        {
            "testId" : "2",
            "details" : {
                "status" : "InProgress"
            }
        },
        {
            "testId" : "3",
            "details" : {
                "status" : "Completed"
            }
        },
    ]
}
我想搜索id为1或2的完整测试。 所以我写了一个类似这样的匹配查询

{
  $match : { $and : [ { "tests.testId" : { $in : [1, 2] } }
                    ,{ "tests.details.status" : "Completed" }
                   ] 
          } 
}
此查询的问题是,即使状态未完成,它也会获取ID为1或2的所有文档。例如,上面的查询获取这两个文档

        {
            "testId" : "1",
            "details" : {
                "status" : "Completed"
            }
        },
        {
            "testId" : "2",
            "details" : {
                "status" : "InProgress"
            }
        },
我需要的是对查询进行修改,以便为这两个条件搜索parituclat数组元素


我还尝试了
$elemMatch
。它仍然不起作用。非常感谢您的帮助。

我们可以使用
聚合
管道和
$filter
仅返回匹配的数组元素

试试这个

db.collection.aggregate([
  {
    $match: { // to filter the documents
      $and: [
        {
          "tests.testId": { $in: ["1", "2"] }
        },
        {
          "tests.details.status": "Completed"
        }
      ]
    }
  },
  {
    $project: { // then use this $project stage to use the $filter operator in it
      tests: {
        $filter: { // this is to filter the tests array
          input: "$tests",
          as: "test",
          cond: {
            $and: [
              {
                $in: [
                  "$$test.testId", ["1", "2"] 
                ]
              },
              {
                $eq: [
                  "$$test.details.status",
                  "Completed"
                ]
              }
            ]
          }
        }
      }
    }
  }
])
你可以在这里测试

希望能有帮助

注意,如果testId是ObjectId类型,那么在聚合管道中必须使用ObjectId而不是字符串


我们可以使用
aggregate
管道和
$filter
仅返回匹配的数组元素

试试这个

db.collection.aggregate([
  {
    $match: { // to filter the documents
      $and: [
        {
          "tests.testId": { $in: ["1", "2"] }
        },
        {
          "tests.details.status": "Completed"
        }
      ]
    }
  },
  {
    $project: { // then use this $project stage to use the $filter operator in it
      tests: {
        $filter: { // this is to filter the tests array
          input: "$tests",
          as: "test",
          cond: {
            $and: [
              {
                $in: [
                  "$$test.testId", ["1", "2"] 
                ]
              },
              {
                $eq: [
                  "$$test.details.status",
                  "Completed"
                ]
              }
            ]
          }
        }
      }
    }
  }
])
你可以在这里测试

希望能有帮助

注意,如果testId是ObjectId类型,那么在聚合管道中必须使用ObjectId而不是字符串


谢谢我是否需要首字母
$match
。有了这个逻辑,它也应该在没有它的情况下工作。不是吗?只有
$project
块可以工作。让我知道您的想法在这种情况下,如果没有它,它将工作是的,但是如果您有其他文档,其中包含测试数组,而其中的任何元素都不匹配您的任何条件,那么我们确实需要它。另外,这个$match更适合通过索引进行mongodb搜索,而不是整个集合扫描,希望它是清晰的,谢谢。我是否需要首字母
$match
。有了这个逻辑,它也应该在没有它的情况下工作。不是吗?只有
$project
块可以工作。让我知道您的想法在这种情况下,如果没有它,它将工作是的,但是如果您有其他文档,其中包含测试数组,而其中的任何元素都不匹配您的任何条件,那么我们确实需要它。另外,这个$match更适合通过索引进行mongodb搜索,而不是整个集合扫描,希望这一点很清楚