用于过滤掉 mongodb 中引用的 ($ref) 数组对象的 $elemMatch 不起作用
$elemMatch for filtering out referenced($ref) array objects in mongodb is not working
我有 2 个集合 student_details 和 subject_details,其中每个学生可以有多个主题,我将它们存储在 student_details 集合中作为参考数组。
现在我需要获取学生详细信息以及 subject_details.status=ACTIVE 中的筛选主题。
如何将 $elemMatch
用于 $ref
对象来实现此目的。
我正在使用类似下面的内容,但它没有返回任何记录。
db.getCollection('student_details').find( { subjects: { $elemMatch: { $ref: "subject_details", status: 'ACTIVE' }}})
student_details
================
{
"_id" : "STD-1",
"name" : "XYZ",
"subjects" : [
{
"$ref" : "subject_details",
"$id" : "SUB-1"
},
{
"$ref" : "subject_details",
"$id" : "SUB-2"
},
{
"$ref" : "subject_details",
"$id" : "SUB-3"
}
]
}
subject_details
===============
{
"_id" : "SUB-1",
"name" : "MATHEMATICS",
"status" : "ACTIVE"
}
{
"_id" : "SUB-2",
"name" : "PHYSICS",
"status" : "ACTIVE"
}
{
"_id" : "SUB-3",
"name" : "CHEMISTRY",
"status" : "INACTIVE"
}
因为它们在 2 个集合中,您需要 $lookUp 将它们放在一起...在此之前,我相信您需要 $unwind the Subjects 数组...这里有点代码,所以这不是一个答案作为一般建议...聚合管道用于分阶段执行这些操作...
我假设你是 post 的缩写...因为如果主题详细信息真的只是 3 个字段,你的模式在 NoSQL 世界中更好地服务于只将该信息与学生详细信息一起使用并使用 1 个集合而不是规范化的关系方法
dbref 用于查找时很麻烦。但您可以使用以下聚合管道解决它:
db.student_details.aggregate([
{
$unwind: "$subjects"
},
{
$set: {
"fk": {
$arrayElemAt: [{
$objectToArray: "$subjects"
}, 1]
}
}
},
{
$lookup: {
"from": "subject_details",
"localField": "fk.v",
"foreignField": "_id",
"as": "subject"
}
},
{
$match: {
"subject.status": "ACTIVE"
}
},
{
$group: {
"_id": "$_id",
"name": {
$first: "$name"
},
"subjects": {
$push: {
$arrayElemAt: ["$subject", 0]
}
}
}
}
])
生成的对象如下所示:
{
"_id": "STD-1",
"name": "XYZ",
"subjects": [
{
"_id": "SUB-1",
"name": "MATHEMATICS",
"status": "ACTIVE"
},
{
"_id": "SUB-2",
"name": "PHYSICS",
"status": "ACTIVE"
}
]
}
我有 2 个集合 student_details 和 subject_details,其中每个学生可以有多个主题,我将它们存储在 student_details 集合中作为参考数组。
现在我需要获取学生详细信息以及 subject_details.status=ACTIVE 中的筛选主题。
如何将 $elemMatch
用于 $ref
对象来实现此目的。
我正在使用类似下面的内容,但它没有返回任何记录。
db.getCollection('student_details').find( { subjects: { $elemMatch: { $ref: "subject_details", status: 'ACTIVE' }}})
student_details
================
{
"_id" : "STD-1",
"name" : "XYZ",
"subjects" : [
{
"$ref" : "subject_details",
"$id" : "SUB-1"
},
{
"$ref" : "subject_details",
"$id" : "SUB-2"
},
{
"$ref" : "subject_details",
"$id" : "SUB-3"
}
]
}
subject_details
===============
{
"_id" : "SUB-1",
"name" : "MATHEMATICS",
"status" : "ACTIVE"
}
{
"_id" : "SUB-2",
"name" : "PHYSICS",
"status" : "ACTIVE"
}
{
"_id" : "SUB-3",
"name" : "CHEMISTRY",
"status" : "INACTIVE"
}
因为它们在 2 个集合中,您需要 $lookUp 将它们放在一起...在此之前,我相信您需要 $unwind the Subjects 数组...这里有点代码,所以这不是一个答案作为一般建议...聚合管道用于分阶段执行这些操作...
我假设你是 post 的缩写...因为如果主题详细信息真的只是 3 个字段,你的模式在 NoSQL 世界中更好地服务于只将该信息与学生详细信息一起使用并使用 1 个集合而不是规范化的关系方法
dbref 用于查找时很麻烦。但您可以使用以下聚合管道解决它:
db.student_details.aggregate([
{
$unwind: "$subjects"
},
{
$set: {
"fk": {
$arrayElemAt: [{
$objectToArray: "$subjects"
}, 1]
}
}
},
{
$lookup: {
"from": "subject_details",
"localField": "fk.v",
"foreignField": "_id",
"as": "subject"
}
},
{
$match: {
"subject.status": "ACTIVE"
}
},
{
$group: {
"_id": "$_id",
"name": {
$first: "$name"
},
"subjects": {
$push: {
$arrayElemAt: ["$subject", 0]
}
}
}
}
])
生成的对象如下所示:
{
"_id": "STD-1",
"name": "XYZ",
"subjects": [
{
"_id": "SUB-1",
"name": "MATHEMATICS",
"status": "ACTIVE"
},
{
"_id": "SUB-2",
"name": "PHYSICS",
"status": "ACTIVE"
}
]
}