Сортировка сводной таблицы в MongoDB

Вопрос или проблема

Как мне отсортировать ответ из таблицы по ключу другой таблицы?

Например:
У меня есть таблица с данными пользователей. Содержимое таблицы:

{ _id:objectId, name:string, age:number}

Теперь у меня есть другая таблица с данными зарплат сотрудников. Содержимое таблицы:

{ _id:objectId userId:objectId //ссылка на пользователя totalSalary:number}

Что я хочу здесь, так это то, что когда я получаю данные из зарплаты сотрудников, я хочу отсортировать результат по имени пользователя (которое находится в таблице пользователей) или по totalSalary (в зависимости от того, что пользователь введет в порядке, упомянутом этим пользователем)

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

Ответ или решение

Кросс-табличная сортировка в MongoDB с помощью Mongoose

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

Структура данных

Вы описали две коллекции в MongoDB:

  1. Коллекция "user data":

    { 
      _id: ObjectId, 
      name: String, 
      age: Number 
    }
  2. Коллекция "employee salary data":

    { 
      _id: ObjectId, 
      userId: ObjectId,  // ссылка на пользователя
      totalSalary: Number 
    }

Для того, чтобы производить сортировку, вам необходимо будет использовать агрегацию, которая позволит объединить данные из обеих коллекций.

Пример кода с использованием агрегатного конвейера

Вот пример кода, который можно использовать в вашем приложении на Mongoose версии 8.4.5. В этом примере мы будем сортировать результаты по имени пользователя или общей зарплате в зависимости от пользовательского ввода.

const mongoose = require('mongoose');

// Ваши модели
const User = mongoose.model('User', new mongoose.Schema({
  name: String,
  age: Number
}));

const EmployeeSalary = mongoose.model('EmployeeSalary', new mongoose.Schema({
  userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
  totalSalary: Number
}));

// Функция для получения и сортировки данных
async function getSortedSalaries(sortBy) {
  try {
    const salaries = await EmployeeSalary.aggregate([
      {
        $lookup: {
          from: 'users', // называйте коллекции в нижнем регистре
          localField: 'userId',
          foreignField: '_id',
          as: 'userInfo'
        }
      },
      {
        $unwind: { path: '$userInfo', preserveNullAndEmptyArrays: true } // Разворачиваем массив
      },
      {
        $project: {
          _id: 1,
          userId: 1,
          totalSalary: 1,
          userName: '$userInfo.name'
        }
      },
      {
        $sort: {
          [sortBy === 'name' ? 'userName' : 'totalSalary']: 1 // Сортировка по имени пользователя или общей зарплате
        }
      }
    ]);

    return salaries;
  } catch (error) {
    console.error('Ошибка получения данных:', error);
    throw error; // можно обработать ошибку как необходимо
  }
}

Объяснение кода

  1. $lookup: Этот оператор объединяет данные из коллекции "employee salary data" с коллекцией "user data". Мы указываем, что поле userId должно соответствовать _id из "user data".

  2. $unwind: Этот оператор используется, чтобы разворачивать массив userInfo, созданный оператором $lookup, в отдельные документы. Это помогает получить удобный доступ к атрибутам пользователя для сортировки и отображения.

  3. $project: Мы выбираем необходимые поля для конечного результата. Здесь мы создаем поле userName, которое будет содержать имя пользователя.

  4. $sort: В этом этапе данные сортируются по выбранному критериям: либо по имени пользователя, либо по общей зарплате.

Заключение

С помощью описанного метода вы можете гибко обрабатывать запросы на сортировку данных в MongoDB с использованием Mongoose. Подход через агрегатные операции является мощным инструментом, позволяющим не только объединять, но и манипулировать данными на более высоком уровне. Вы можете расширять и адаптировать этот код по мере необходимости для решения более сложных задач анализа данных.

Оцените материал
Добавить комментарий

Капча загружается...