0

I have 2 collection types in my Strapi setup: product and review where a product has many reviews.

I want to add 2 new fields to the response of /products and /products/:id:

averageRaing: number
totalReviews: number

I want to override the default find service to implement this, but I am unable to find the source code for strapi.query("product").find(params, populate) to override it.

If possible, I need this done in a single query rather than making multiple queries.

So far I have:

find(params, populate) {
  return strapi.query("product").model.query(db => {
    // I want the same query as when I run `strapi.query("product").find(params, populate)`
  });
},

But I am unsure of how to handle the params and populate in the exact same way that .find(params, populate) does.

Ari Seyhun
  • 11,506
  • 16
  • 62
  • 109

1 Answers1

0

After digging into the source code, I found a solution:

const { convertRestQueryParams, buildQuery } = require("strapi-utils");

function find(params, populate) {
  const model = strapi.query("product").model;
  const filters = convertRestQueryParams(params);
  const query = buildQuery({ model, filters });

  return model
    .query((qb) => {
      const totalReviewsQuery = strapi.connections
        .default("reviews")
        .count("*")
        .where("product", strapi.connections.default.ref("products.id"))
        .as("total_reviews");

      const averageRatingQuery = strapi.connections
        .default("reviews")
        .avg("rating")
        .where("product", strapi.connections.default.ref("products.id"))
        .as("average_rating");

      query(qb);

      qb.column("*", totalReviewsQuery, averageRatingQuery);
    })
    .fetchAll({
      withRelated: populate,
      publicationState: filters.publicationState,
    })
    .then((results) => results.toJSON());
}
Ari Seyhun
  • 11,506
  • 16
  • 62
  • 109