Вопрос:

Как скопировать информацию «type» в «instance» в агрегации монго и Lookup ... и сохранить исходный список?

mongodb types aggregate instance lookup

20 просмотра

1 ответ

1 Репутация автора

Во время агрегации монго я пытаюсь скопировать информацию о типе в «экземпляр» ... и вернуть исходную структуру объекта без изменений.

Некоторое уточнение: Инстанция означает, что у пациента есть запись о том, что у него есть лекарство «Асприн». Он содержит только идентификатор лекарства и дату начала и окончания. Не вся информация о лекарствах. В другой коллекции представлены все виды возможных лекарств. Один из них мы называем экземпляром, а позднее - типом.

Что я пытаюсь сделать, так это когда мы забираем пациента, мы, конечно, также возвращаем все лекарства этому пациенту. Но тогда мне нужно взять 5 лекарств на «копии» пациента с названием и описанием типа. Конечным результатом будет полная запись о пациенте, включая лекарства, с добавлением названия лекарства и описания типа.

В коде я бы просто перебрал каждое лекарство, а затем запросил тип, используя идентификатор лекарства, и установил имя. Это должно быть очень легко сделать в БД.

Попытка сделать это в коде стихов БД.

Пример: у меня есть коллекция типов лекарств. Каждый тип имеет имя, идентификатор и дозировку и т. Д.

`

db.medications.insert([
                {"medicationId": "1","Name": "Asprin",... },
                {"medicationId": "2","Name": "Tylenol", ... }]);

`

И в истории болезни пациента есть список лекарств. db.patients.insert([{ "firstName": "patient1", "medications": [ {"medicationId":"1", ... }, {"medicationId":"2", ... }, ] } и то, что я пытаюсь сделать, - это просто ввести имя в каждом «экземпляре» лекарства для пациента, сопоставив идентификатор лекарства в коллекции типов.

Это очень распространенный шаблон для нас, где мы всегда храним много информации о типе, но пример действительно плотный. Но мы хотим показать информацию о типе в некоторых случаях (например, имя и описание), когда мы показываем запись пациента.

Я не могу понять, как сделать набор как часть конвейера поиска. Кажется, я могу только возвратить список лекарств, которые соответствуют идентификатору лекарства, но затем я теряю первоначальный набор.

Я попробовал нижеследующее, но оно просто заменяет лекарство на лекарство из коллекции типов.

{ $lookup: { from: "medications", localField: "medications.medicationId", foreignField: "medicationId", as: "medications" }, })

Я был бы счастлив, если бы они были просто объединены .. Я пробовал это, но объединение как-то не разрешено в конвейере поиска? Хорошая новость заключается в том, что вышесказанное оставляет исходную запись «пациента» нетронутой, чего я и хочу, но теперь мне просто нужно как-то объединить их

Автор: Raphael Источник Размещён: 10.08.2019 03:38

Ответы (1)


0 плюса

517 Репутация автора

Допустим, у вас есть следующие данные в БД:

medications:
    {
        "_id" : ObjectId("5d4fc7c8a412da1f166525e5"),
        "medicationId" : "1",
        "Name" : "Asprin"
    }
    {
        "_id" : ObjectId("5d4fc7c8a412da1f166525e6"),
        "medicationId" : "2",
        "Name" : "Tylenol"
    }

patients:
{
    "_id" : ObjectId("5d4fc7eaa412da1f166525e7"),
    "firstName" : "patient1",
    "medications" : [
        {
            "medicationId" : "1"
        },
        {
            "medicationId" : "2"
        }
    ]
}

Следующий запрос может дать нам ожидаемый результат:

db.patients.aggregate([
    {
        $unwind:"$medications"
    },
    {
        $lookup:{
            "from":"medications",
            "localField":"medications.medicationId",
            "foreignField":"medicationId",
            "as":"medicationsLookup"
        }
    },
    {
        $unwind:{
            "path":"$medicationsLookup",
            "preserveNullAndEmptyArrays":true
        }
    },
    {
        $addFields:{
            "medications.Name":"$medicationsLookup.Name"
        }
    },
    {
        $group:{
            "_id":"$_id",
            "firstName":{
                $first:"$firstName"
            },
            "medications":{
                $push:"$medications"
            }
        }
    }
]).pretty()

Выход:

{
    "_id" : ObjectId("5d4fc7eaa412da1f166525e7"),
    "firstName" : "patient1",
    "medications" : [
        {
            "medicationId" : "1",
            "Name" : "Asprin"
        },
        {
            "medicationId" : "2",
            "Name" : "Tylenol"
        }
    ]
}

Примечание: обе коллекции до сих пор не повреждены

Детали этапов агрегации:

  • Стадия I: раскручивает массив лекарств
  • Стадия II: Поиск каждого идентификатора лекарства из массива с идентификатором лекарства, присутствующим в коллекции «лекарства»
  • Этап III: добавить новое поле «Имя» в конвейер
  • Этап IV: группировка данных на основе идентификатора объекта
Автор: MrSSharma Размещён: 11.08.2019 08:01
Вопросы из категории :
32x32