Я не могу заставить работать метод Mongoose Aggregate

Я создаю API, и я хотел использовать методы пропуска и ограничения в mongoose для обработки нумерации страниц. Я хотел бы получить общий размер документа вместе с данными о нумерации страниц. Первоначально я сделал два запроса: один для данных с разбивкой на страницы, а другой для общего размера документа. Это плохо, да? Я начал искать, есть ли встроенный способ справиться с этим в одном запросе. Я столкнулся с агрегатным методом. К сожалению, мне не удалось заставить его работать.

Вот мои коды с двумя запросами:

const page = req.query.page
 const {skip, searchlimit} = getPagination(params);
let transactionsData = []

const transactions = await TransactionModel.find({transactionOwnerId: user?._id}).sort({createdAt:-1})
  .skip(skip)
  .limit(searchlimit);

 totalDocumentSize = await TransactionModel.countDocuments({transactionOwnerId:   user?._id});

  transactionsData = transactions as transactionAttributes[];

console.info(transactionsData, totalDocumentSize)

Здесь я попробовал агрегатный метод:

 const me = await TransactionModel.aggregate([{
           $match: {transactionOwnerId: user?._id}
        }, 
         {
            $sort: {createdAt:-1}
         }
        
     ]);
console.info(me);

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

Я опубликовал свой ответ. Пожалуйста, проверьте и дайте мне знать.

Subha 23.06.2024 12:07
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
91
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вам стоит попробовать с $facet.

Попробуйте это. Я думаю, это сработает.

const me = await TransactionModel.aggregate([
      { $match: { transactionOwnerId: user?._id } },
      {
        $facet: {
          transactions: [
            { $sort: { createdAt: -1 } },
            { $skip: skip },
            { $limit: limit },
          ],
          totalDocumentSize: [
            { $count: 'count' }
          ]
        }
      }
    ]);

А затем извлеките каждую запись, используя...

const transactions = me[0].transactions;
const totalDocumentSize = me[0].totalDocumentSize[0]?.count || 0;

Примечание. Обязательно запустите этот запрос внутри функции async().

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

valve 23.06.2024 20:35

Пожалуйста, проверьте, являются ли переменные skip и limit (в вашем случае searchlimit) числом и находятся ли они в пределах диапазона.

Subha 23.06.2024 20:45

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

valve 23.06.2024 22:51

Это работает после того, как я преобразовал идентификатор объекта в строку. пользователь?.id?.toString(). Спасибо за помощь.

valve 25.06.2024 10:24

@valve, я рад помочь вам. Пожалуйста, примите ответ, чтобы посетители могли использовать его позже.

Subha 25.06.2024 10:27

попробуй это!

    const page = parseInt(req.query.page) || 1;
    const limit = 10;

    const transactions = await TransactionModel.aggregate([
      {
        $match: {
          $expr: { $eq: ["$transactionOwnerId", { $toObjectId: user?._id }] },
        },
      },
      {
        $facet: {
          data: [
            {
              $skip: (page - 1) * limit,
            },
            {
              $limit: limit,
            },
            {
              $sort: { createdAt: -1 },
            },
          ],
          count: [
            {
              $count: "count",
            },
          ],
        },
      },
    ]);

    console.info(transactions);

Другие вопросы по теме