Мне нужно извлечь данные в виде пар ключ-значение из коллекции записей и объединить их в родительскую запись в mongoDB - PullRequest
2 голосов
/ 04 марта 2020

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

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

Таким образом, когда я обновляю Поле «значение» в CustomPicklistValue везде, где на эту запись ссылаются через идентификатор, оно будет использовать новое значение.

enter image description here

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

rawCollection
        .aggregate(
            [
                {
                    $match: {
                        createdAt: {
                            $gte: rangeEndDate,
                            $lte: rangeStartDate
                        },
                        ...$match
                    }
                },
                {
                    $project: {
                        ...$project,
                        total: $projectAggregation
                    }
                },
                {
                    $group: {
                        _id: {
                            ...$groupKey
                        },
                        total: {
                            [`$${aggrAttrFunc}`]: "$total"
                        }
                    }
                }
            ],
            {
                cursor: {
                    batchSize: 100
                }
            }
        )

Вот основная часть метода для извлечения и агрегирования любых моделей, хранящихся в моем экземпляре mongodb. Пользователь может указать целый ряд вещей, включая, но не ограничиваясь, модель, поле, указывающее c диапазоны дат и фильтры, такие как «где статус сертификата истек» и т. Д. c.

Итак, я теперь представлены с такой структурой данных:

{
    id: '5e5fb732a9422a001146509f',
    customPicklistValues: [
        {
            id: '5e4e904f16ab94bff1a324a0',
            value: 'Internal',
            fieldName: 'Business Group',
            customPicklist: '109c7a1a9d00b664f2ee7827'
        },
        {
            id: '5e4e904f16ab94bff1a324a4',
            value: 'Slack',
            fieldName: 'Application',
            customPicklist: '109c5a1a9d00b664f2ee7827'
        }
    ],
}

И для моей жизни не получится, если есть какой-то способ, которым я могу по существу извлечь fieldName и value для каждой из заполненных записей как пары ключ-значение и добавьте каждую в родительскую запись перед запуском моего предложения о совпадении ...

Я думаю, что мне нужно использовать поиск, чтобы сначала заполнить customPicklistValues, а затем как-то объединить их?

Любая помощь приветствуется.

РЕДАКТИРОВАТЬ:

@ whoami предложила использовать $ addFields. Перед тем, как $ addFields заполнил связанные записи, мне пришлось потратить немало средств (из-за того, как Waterline использует паруса. js обрабатывает сохранение Mon go ObjectID в связанных коллекциях в виде строк), мои шаги в компасе вы можете увидеть здесь :

enter image description here

Последним шагом будет редактирование этого или добавление к нему этапа, чтобы фактически иметь возможность поддерживать пару ключ: значение, например Business Group: "Finance" в этом примере.

1 Ответ

1 голос
/ 05 марта 2020

Вы можете попробовать эти этапы после этапа $lookup:

db.collection.aggregate([
    {
        $addFields: {
            customPicklistValues:
            {
                $arrayToObject: {
                    $map: {
                        input: '$customPicklistValues',
                        in: { k: '$$this.fieldName', v: '$$this.value' }
                    }
                }
            }
        }
    },
    { $replaceRoot: { newRoot: { $mergeObjects: ['$customPicklistValues', '$$ROOT'] } } },
    { $project: { customPicklistValues: 0 } }
])

Тест: MongoDB-Playground

...