如何从 Strapi 内容 API 获取随机记录

问题描述 投票:0回答:6

我在 Strapi 中有记录。我正在使用 Strapi 内容 API。在我的前端,我只需要随机显示 2 条记录。为了进行限制,我使用了内容 API 的限制查询。但随机获取我需要使用的关键字。官方文档没有提供任何有关此的详细信息 - https://strapi.io/documentation/v3.x/content-api/parameters.html#available-operators

strapi
6个回答
5
投票

随机没有官方的 Strapi API 参数。你必须实施你自己的。以下是我之前使用 Strapi v3 所做的事情:

1 - 制作服务功能

文件:

api/mymodel/services/mymodel.js

这将包含我们实际的随机查询(SQL),将其包装在服务中很方便,因为它可以在很多地方使用(cron 作业、其他模型内部等)。

module.exports = {
    serviceGetRandom() {

        return new Promise( (resolve, reject) => {
            
            // There's a few ways to query data.
            // This example uses Knex.
            const knex = strapi.connections.default
            let query = knex('mydatatable')

            // Add more .select()'s if you want other fields
            query.select('id')

            // These rules enable us to get one random post
            query.orderByRaw('RAND()')
            query.limit(1)

            // Initiate the query and do stuff
            query
            .then(record => {
                console.log("getRandom() record: %O", record[0])
                resolve(record[0])
            })
            .catch(error => {
                reject(error)
            })
        })
    }
}

2 - 在某个地方使用该服务,例如控制器:

文件:

api/mymodel/controllers/mymodel.js

module.exports = {

    //(untested)

    getRandom: async (ctx) => {

        await strapi.services.mymodel.serviceGetRandom()
        .then(output => {
            console.log("getRandom output is %O", output.id)
            ctx.send({
                randomPost: output
            }, 200)
        })
        .catch( () => {
            ctx.send({
                message: 'Oops! Some error message'
            }, 204) // Place a proper error code here
        })

    }

}

3 - 创建一条指向此控制器的路由

文件:

api/mymodel/config/routes.json

...
    {
        "method": "GET",
        "path": "/mymodelrandom",
        "handler": "mymodel.getRandom",
        "config": {
            "policies": []
        }
    },
...

4 - 在您的前端中,访问路线

(无论您如何访问 API)

例如ajax 调用

/api/mymodelrandom


4
投票

这似乎对我来说适用于 Strapi v.4 REST API

控制器,获取6个随机条目

"use strict";

/**
 *  artwork controller
 */

const { createCoreController } = require("@strapi/strapi").factories;

module.exports = createCoreController("api::artwork.artwork", ({ strapi }) => {
  const numberOfEntries = 6;
  return {
    async random(ctx) {
      const entries = await strapi.entityService.findMany(
        "api::artwork.artwork",
        {
          populate: ["image", "pageHeading", "seo", "socialMedia", "artist"],
        }
      );

      const randomEntries = [...entries].sort(() => 0.5 - Math.random());
      ctx.body = randomEntries.slice(0, numberOfEntries);
    },
  };
});

路线 随机.js

"use strict";

module.exports = {
  routes: [
    {
      method: "GET",
      path: "/artwork/random",
      handler: "artwork.random",
      config: {
        auth: false,
      },
    },
  ],
};

API

http://localhost:1337/api/artwork/random

匹配 Strapi 的默认数据结构

"use strict";

/**
 *  artwork controller
 */

const { createCoreController } = require("@strapi/strapi").factories;

module.exports = createCoreController("api::artwork.artwork", ({ strapi }) => {
  const numberOfEntries = 6;
  return {
    async random(ctx) {
      const entries = await strapi.entityService.findMany(
        "api::artwork.artwork",
        {
          populate: ["image", "pageHeading", "seo", "socialMedia", "artist"],
        }
      );

      const randomEntries = [...entries]
        .sort(() => 0.5 - Math.random())
        .slice(0, numberOfEntries);

      const structureRandomEntries = {
        data: randomEntries.map((entry) => {
          return {
            id: entry.id,
            attributes: entry,
          };
        }),
      };

      ctx.body = structureRandomEntries;
    },
  };
});

还有一个随机排序插件。 https://www.npmjs.com/package/strapi-plugin-random-sort


3
投票

没有用于获取随机结果的 API 参数。

所以:FrontEnd 是针对您的问题的推荐解决方案。

您需要创建一个随机请求范围,然后从该范围中获取一些随机项目。

function getRandomInt(max) {
  return Math.floor(Math.random() * Math.floor(max));
}
const firstID = getRandomInt(restaurants.length);
const secondID = getRandomInt(3);
const query = qs.stringify({
  id_in:[firstID,secondID ] 
});
// request query should be something like GET /restaurants?id_in=3&id_in=6

2
投票

可靠地做到这一点的一种方法是通过两个步骤:

  1. 获取总记录数
  2. 使用
    _start
    _limit
    参数获取记录数
// Untested code but you get the idea

// Returns a random number between min (inclusive) and max (exclusive)
function getRandomArbitrary(min, max) {
    return Math.random() * (max - min) + min;
}

const { data: totalNumberPosts } = await axios.get('/posts/count');

// Fetch 20 posts
const _limit = 20;

// We need to be sure that we are not fetching less than 20 posts
// e.g. we only have 40 posts. We generate a random number that is 30.
// then we would start on 30 and would only fetch 10 posts (because we only have 40)
const _start = getRandomArbitrary(0, totalNumberPosts - _limit);

const { data: randomPosts } = await axios.get('/posts', { params: { _limit, _start } })

这种方法的问题在于它需要两次网络请求,但对于我的需求来说,这不是问题。


1
投票

这似乎对我来说适用于 Strapi v4.3.8 和 graphql

src/index.js

"use strict";

module.exports = {

  register({ strapi }) {
    const extensionService = strapi.service("plugin::graphql.extension");

    const extension = ({ strapi }) => ({
      typeDefs: `
        type Query {
          randomTestimonial: Testimonial
        }
      `,
      resolvers: {
        Query: {
          randomTestimonial: async (parent, args) => {
            const entries = await strapi.entityService.findMany(
              "api::testimonial.testimonial"
            );
            const sanitizedRandomEntry =
              entries[Math.floor(Math.random() * entries.length)];

            return sanitizedRandomEntry;
          },
        },
      },
      resolversConfig: {
        "Query.randomTestimonial": {
          auth: false,
        },
      },
    });

    extensionService.use(extension);
  },
  bootstrap({ strapi }) {},
};

graphql 查询:

  query GetRandomTestimonial {
    randomTestimonial {
      __typename
      name
      position
      location
      description
    }
  }

生成有关路线更改/刷新的随机推荐 https://jungspooner.com/biography


0
投票

使用

Postgres
和knex:

let { rows } = await strapi.db.connection.raw(
    `select id from posts where published_at IS NOT null order by random() limit ${count};`
);

如何在strapi v4 typescript上进行原始sql查询

© www.soinside.com 2019 - 2024. All rights reserved.