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.$
db.collection.find({
"replies.isApproved": false
},
{
"replies.$": 1,
"_class": 1,
"discussion_id": 1
})
获取数组不匹配的其他元素:
db.collection.find({},
{
"replies": {
$elemMatch: {
"isApproved": false
}
},
"_class": 1,
"discussion_id": 1
})
编辑:
db.collection.find({
"isApproved": false
},
{
"replies": {
$elemMatch: {
"isApproved": false
}
},
"_class": 1,
"discussion_id": 1
})
我正在使用 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.$
db.collection.find({
"replies.isApproved": false
},
{
"replies.$": 1,
"_class": 1,
"discussion_id": 1
})
获取数组不匹配的其他元素:
db.collection.find({},
{
"replies": {
$elemMatch: {
"isApproved": false
}
},
"_class": 1,
"discussion_id": 1
})
编辑:
db.collection.find({
"isApproved": false
},
{
"replies": {
$elemMatch: {
"isApproved": false
}
},
"_class": 1,
"discussion_id": 1
})