$ elemMatch для фильтрации объектов ссылочного массива ($ ref) в mongodb не работает - PullRequest
1 голос
/ 18 февраля 2020

У меня есть 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 ]

1 голос
/ 19 февраля 2020

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"
        }
    ]
}
0 голосов
/ 19 февраля 2020

, потому что они находятся в 2 коллекциях, вам нужно $ lookUp, чтобы собрать их вместе ... перед этим я считаю, что вам нужно $ раскрутить массив Subjects ... вроде кода здесь, так что это не столько ответ, сколько общий совет ... конвейер агрегации используется, чтобы сделать это поэтапно ...

я предполагаю, что вы сокращаете для поста ... потому что, если Subject Details действительно только 3 поля, ваша схема лучше обслуживается в Нет SQL мира, чтобы просто поместить эту информацию в Сведения об ученике и использовать 1 коллекцию вместо нормализованного реляционного подхода

...