首页 > 解决方案 > Strapi GraphQL 默认排序

问题描述

我正在使用带有突变“generateQuiz”的 Strapi 版本 3.4.6 来生成一个带有一组来自问题池的随机问题的测验。在控制器中,我查询所有问题(效率低下,我知道,但目前还可以),随机排列问题并从随机列表中选择前 x 个问题。当问题池包含少于 x 个问题时,我希望得到一个包含所有可用问题的随机排序列表的测验。当我查询 REST-API 时就是这种情况,但当我查询 GraphQL-API 时不是。GraphQL 返回一个测验,其中的问题总是按其 ID 排序。

示例:假设我们有一个包含 9 个问题(ID 1 到 9)的问题库,并且我们希望生成一个最多包含 10 个问题的测验。在 generateQuiz 控制器中发生以下情况:

  1. 从数据库中查询所有 (9) 个问题
  2. 洗牌
  3. 从 9 个问题中取 10 个 -> 结果仍然是 9 个问题
  4. 用问题创建一个新测验
  5. 返回

当我调用 REST-API 时,我会收到一个包含以下问题列表的测验:[5,3,2,8,6,1,4,9,7]

当我调用 GraphQL-API 时,我总是得到一个带有问题排序列表的测验:[1,2,3,4,5,6,7,8,9]

为什么会这样?我可以改变这种行为吗?

代码

控制器代码:

    async generateQuiz(ctx) {
        const {questionCount, includeSubcategories} = ctx.request.body;
        const categoryId = ctx.request.body.categoryId ? Number(ctx.request.body.categoryId) : undefined;

        const userId = ctx.state.user.id;

        let params = {
            userId,
            // eslint-disable-next-line camelcase
            deadline_gte: new Date(),
            // eslint-disable-next-line camelcase
            finishedAt_null: true,
            category: categoryId,
            // eslint-disable-next-line camelcase
            category_null: categoryId ? undefined : true
        };

        // remove undefined properties
        params = _.pickBy(params, v => v !== undefined);

        const quiz = await strapi.services.quiz.findOne(params);

        if (quiz) {
            throw strapi.errors['badRequest'](`An active quiz with categoryId ${categoryId} already exists. quizId: ${quiz.id}`);
        }

        let questions;
        if (categoryId) {
            const searchCategories = await strapi.services.category.list(categoryId, includeSubcategories);
            const searchCategoryIds = _.map(searchCategories, 'id');

            // eslint-disable-next-line camelcase
            questions = await strapi.services['quiz-question'].find({category_in: searchCategoryIds}, []);
        }
        else {
            if (includeSubcategories !== false) {
                questions = await strapi.services['quiz-question'].find({}, []);
            } else {
                throw strapi.errors['badRequest'](`includeSubcategories cannot be set to false when no categoryId is specified`);
            }
        }

        // get question IDs
        let questionIds = _.map(questions, 'id');

        // shuffle
        questionIds = _.shuffle(questionIds);

        // take first x question IDs
        if (questionCount) {
            questionIds = _.take(questionIds, questionCount);
        }

        strapi.log.debug('questionIds',questionIds);

        // get number of questions
        const quizQuestionCount = questionIds.length;

        const now = _.now();
        const deadline = now + (quizQuestionCount * strapi.config.get('server.app.secondsPerQuestionInQuiz', 60) * 1000);

        const data = {
            startedAt: now,
            finishedAt: null,
            deadline,
            userId,
            questions: questionIds,
            category: categoryId
        };

        const newQuiz = await strapi.services.quiz.create(data);

        strapi.log.debug('newQuiz question ids', _.map(newQuiz.questions,'id'));

        return newQuiz;
    },

graphql 查询:

mutation {
  generateQuiz(questionCount: 15) {
    id
    questions {
      id
    }
  }
}

示例控制台输出:

[2021-02-18T08:56:14.622Z] debug questionIds [2,9,1,5,7,6,4,8,3]
[2021-02-18T08:56:14.711Z] debug newQuiz question ids [5,2,6,9,4,8,3,1,7]

graphql 查询结果:

{
  "data": {
    "generateQuiz": {
      "id": "91",
      "questions": [
        {
          "id": "1"
        },
        {
          "id": "2"
        },
        {
          "id": "3"
        },
        {
          "id": "4"
        },
        {
          "id": "5"
        },
        {
          "id": "6"
        },
        {
          "id": "7"
        },
        {
          "id": "8"
        },
        {
          "id": "9"
        }
      ]
    }
  }
}

api 结果(删除了不必要的数据):

{
    "id": 88,
    ...
    "questions": [
        {
            "id": 5,
            ...
        },
        {
            "id": 3,
            ...
        },
        {
            "id": 2,
            ...
        },
        {
            "id": 8,
            ...
        },
        {
            "id": 6,
            ...
        },
        {
            "id": 1,
            ...
        },
        {
            "id": 4,
            ...
        },
        {
            "id": 9,
            ...
        },
        {
            "id": 7,
            ...
        }
    ]
}

BR,斯特凡

标签: graphqlstrapi

解决方案


推荐阅读