GraphQL Dataloader vs Mongoose Populate - PullRequest
       6

GraphQL Dataloader vs Mongoose Populate

0 голосов
/ 05 октября 2018

Чтобы выполнить операцию, подобную соединению, мы можем использовать как GraphQL, так и Mongoose для достижения этой цели.

Прежде чем задать какой-либо вопрос, я хотел бы привести следующий пример задания / деятельности (ни один из этого кода не проверен, он дан только для примера):

Task {
  _id,
  title,
  description,
  activities: [{ //Of Activity Type
    _id,
    title
  }]
}

В mongoose мы можем получить действия, связанные с задачей, с помощью метода populate , примерно так:

const task = await TaskModel.findbyId(taskId).populate('activities');

Используя GraphQL и Dataloader, мы можем получить тот же результат с чем-нибудьнапример:

const DataLoader = require('dataloader');
const getActivitiesByTask = (taskId) => await ActivityModel.find({task: taskId});
const dataloaders = () => ({
    activitiesByTask: new DataLoader(getActivitiesByTask),
});
// ...
// SET The dataloader in the context
// ...

//------------------------------------------
// In another file
const resolvers = {
    Query: {
        Task: (_, { id }) => await TaskModel.findbyId(id),
    },
    Task: {
        activities: (task, _, context) => context.dataloaders.activitiesByTask.load(task._id),
    },
};

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

Любое понимание будет полезно, спасибо!

1 Ответ

0 голосов
/ 05 октября 2018

Важно отметить, что загрузчики данных - это не просто интерфейс для ваших моделей данных.Хотя загрузчики данных рекламируются как «упрощенный и согласованный API по сравнению с различными удаленными источниками данных», их основное преимущество в сочетании с GraphQL заключается в возможности реализации кэширования и пакетирования в контексте одного запроса.Такая функциональность важна в API, которые имеют дело с потенциально избыточными данными (подумайте о том, чтобы опрашивать пользователей и друзей каждого пользователя - есть огромный шанс многократного повторного получения одного и того же пользователя).

С другой стороны, mongoose'sМетод populate - это на самом деле просто способ объединения нескольких запросов MongoDB.В этом смысле сравнивать эти два значения - все равно, что сравнивать яблоки и апельсины.

Более справедливое сравнение может заключаться в использовании populate, как показано в вашем вопросе, а не в добавлении преобразователя для activities в следующих строках:

activities: (task, _, context) => Activity.find().where('id').in(task.activities)

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

Если запрашивается поле activities, оба подходавыполнит одинаковое количество циклов обработки между сервером и базой данных - разница в производительности, вероятно, будет незначительной.Однако ваш запрос может вообще не включать поле activities.В этом случае распознаватель activities никогда не будет вызван, и мы можем сохранить один или несколько запросов к базе данных, создав отдельный распознаватель activities и выполнив там работу.

В соответствующей заметке...

Насколько я понимаю, агрегирование запросов в MongoDB с использованием чего-то вроде $lookup обычно менее производительно, чем просто использование populate (некоторые разговоры по этому вопросу можно найти здесь ).Однако в контексте реляционных баз данных необходимо учитывать дополнительные соображения при рассмотрении вышеуказанных подходов.Это потому, что ваша первоначальная выборка в родительском распознавателе может быть выполнена с помощью объединений, что обычно будет намного быстрее, чем выполнение отдельных запросов к базе данных.Это означает, что за счет замедления запросов без полей вы можете выполнять другие запросы значительно быстрее.

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