Spring 数据 Mongo DB Criteria 查询以根据条件过滤嵌套文档

Spring Data Mongo DB Criteria query to filter nested documents based on condition

我正在使用 Spring 数据 Mongo 获取包含嵌套文档的文档。 如果特定条件匹配,我正在尝试获取文档并在其中包含嵌套文档,或者只给我父文档。如果有任何回复,isApproved 状态为真,我需要父文档和嵌套文档,否则只获取父文档。 下面是示例数据集,

Sample Data Set:
{
"_id" : ObjectId("5efe3d1f8a2ef008249f72d9"),
"_class" : "com.text.TestInfo",
"discussion_id" : "5efcbbdee87e6d1a706d3a4a",
"content" : "edited comment",
"title" : "Test",
"isApproved" : true,
"replies" : [
  {
  "_id" : ObjectId("59nts64j3cdcds3449f72d9"),
  "content" : "Sample text",
  "isApproved" : false
  },
  {
  "_id" : ObjectId("0j93k099vcdkfdf3vdf372d9"),
  "content" : "Sample text",
  "isApproved" : true
  }   
  ]
 },
 {
"_id" : ObjectId("5efe3d189ms908249f72d9"),
"_class" : "com.text.TestInfo",
"discussion_id" : "5efcbbdee87e6d1a706d3a4a",
"content" : "new eidted comment",
"title" : "Test",
"isApproved" : true,
"replies" : [
  {
  "_id" : ObjectId("59nts64j3cdcds3449f72d9"),
  "content" : "Sample text",
  "isApproved" : false
  }
  ]
 },
 {
"_id" : ObjectId("5efe390d9sds249f72d9"),
"_class" : "com.text.TestInfo",
"discussion_id" : "5efcbbdee87e6d1a706d3a4a",
"content" : "new eidted comment",
"title" : "Test",
"isApproved" : false,
"replies" : [
  {
  "_id" : ObjectId("59nts64j3cdcds3449f72d9"),
  "content" : "dasdsatext",
  "isApproved" : true
  }
  ]
 }

所以,上面是一个文档中的数据集,有两个子文档,在 下一个只有一个子文档。以下是预期的输出。

Expected Output:
{
"_id" : ObjectId("5efe3d1f8a2ef008249f72d9"),
"_class" : "com.text.TestInfo",
"discussion_id" : "5efcbbdee87e6d1a706d3a4a",
"content" : "edited comment",
"title" : "Test",
"isApproved" : true,
"replies" : [
  {
  "_id" : ObjectId("0j93k099vcdkfdf3vdf372d9"),
  "content" : "Sample text",
  "isApproved" : true
  }   
  ]
},
{
"_id" : ObjectId("5efe3d189ms908249f72d9"),
"_class" : "com.text.TestInfo",
"discussion_id" : "5efcbbdee87e6d1a706d3a4a",
"content" : "new eidted comment",
"title" : "Test",
"replies" : []
}

以下是我尝试使用 Spring Data MongoDB

的 2 种方法
First Way:
Query query = new Query();
    Criteria criteria = new Criteria().andOperator(Criteria.where("discussion_id").
    is(new ObjectId("5efe3d1f8a2ef008249f72d9"))).and("replies").elemMatch(Criteria.where("isApproved").ne(true));
    query.addCriteria(criteria);
    List<TestInfo> listOfInfos = mongoOps.find(query, TestInfo.class);

结果我收到的是完全单独的第一份文件,不能满足我的要求。

Second Way:
Query query = new Query();
    Criteria criteria = new Criteria().andOperator(Criteria.where("discussion_id").
    is(new ObjectId("5efe3d1f8a2ef008249f72d9")));
    query.addCriteria(criteria);
    query.fields().elemMatch(Criteria.where("isApproved").ne(true));
    List<TestInfo> listOfInfos = mongoOps.find(query, TestInfo.class);

此处的输出仅是第一个文档中存在的回复子文档父文档值为空。

请告诉我我犯了什么错误

您需要使用 $project。要仅 return 匹配的数组元素,请使用 replies.$

play

db.collection.find({
  "replies.isApproved": false
},
{
  "replies.$": 1,
  "_class": 1,
  "discussion_id": 1
})

获取数组不匹配的其他元素:

play

db.collection.find({},
{
  "replies": {
    $elemMatch: {
      "isApproved": false
    }
  },
  "_class": 1,
  "discussion_id": 1
})

编辑:

play

db.collection.find({
  "isApproved": false
},
{
  "replies": {
    $elemMatch: {
      "isApproved": false
    }
  },
  "_class": 1,
  "discussion_id": 1
})