我要优化的查询使用下表:
我当前的(工作但未优化的)查询在“锻炼”模型(存储为范围)中看起来像这样
exercise_with_metrics_and_tags_and_categories_related(ids) {
return {
// no need for that part here
attributes: [
"id",
"title",
"description",
"version",
"createdAt",
"updatedAt"
],
where: {
id: {
[Op.in]: ids
}
},
include: [
// load exercise evaluation
{
model: sequelize.models.Exercise_Metrics,
as: "metrics",
required: true,
attributes: [
["vote_count", "votes"],
["avg_vote_score", "avg_vote"]
]
},
// load tags linked to this exercise ( with their category included )
// required : true for inner join (by default, it uses left outer join which is bad )
{
model: sequelize.models.Tag,
as: "tags",
required: true,
// credits to Stackoverflow : https://stackoverflow.com/a/45093383/6149867
through: {attributes: []}, //<-- this line will prevent mapping object from being added
attributes: [
["id", "tag_id"],
["text", "tag_text"]
],
include: [
{
model: sequelize.models.Tag_Category,
as: "category",
required: true,
attributes: [
["id", "category_id"],
["kind", "category_text"]
]
}
]
}
]
}
}
我用调用的:
const ids = [/*Some ids I got from other query*/];
models
.Exercise
.scope({
method: ["exercise_with_metrics_and_tags_and_categories_related", ids]
})
.findAll()
哪个给了我以下sql查询:
SELECT "Exercise"."id",
"Exercise"."title",
"Exercise"."description",
"Exercise"."version",
"Exercise"."createdAt",
"Exercise"."updatedAt",
"metrics"."id" AS "metrics.id",
"metrics"."vote_count" AS "metrics.votes",
"metrics"."avg_vote_score" AS "metrics.avg_vote",
"tags"."id" AS "tags.id",
"tags"."id" AS "tags.tag_id",
"tags"."text" AS "tags.tag_text",
"tags->Exercise_Tag"."exercise_id" AS "tags.Exercise_Tag.exercise_id",
"tags->Exercise_Tag"."tag_id" AS "tags.Exercise_Tag.tag_id",
"tags->category"."id" AS "tags.category.id",
"tags->category"."id" AS "tags.category.category_id",
"tags->category"."kind" AS "tags.category.category_text"
FROM "exercises_library"."Exercises" AS "Exercise"
INNER JOIN "exercises_library"."Exercises_Metrics" AS "metrics" ON "Exercise"."id" = "metrics"."exercise_id"
INNER JOIN ("exercises_library"."Exercises_Tags" AS "tags->Exercise_Tag"
INNER JOIN "exercises_library"."Tags" AS "tags" ON "tags"."id" = "tags->Exercise_Tag"."tag_id") ON "Exercise"."id" = "tags->Exercise_Tag"."exercise_id"
INNER JOIN "exercises_library"."Tag_Categories" AS "tags->category" ON "tags"."category_id" = "tags->category"."id"
WHERE "Exercise"."id" IN (2,
3);
如果联接“ Exercise-Exercise_Metrics”的联接可以忽略不计(它是1:1的多重性),则其余查询则不然。我希望Sequelize在加入Exercise(和Exercise_Metrics)之前,对嵌套关联(Exercise_Tags,Tag,Tag,Tag_Category)进行聚合。
我知道Postgresql具有生成json聚合的功能:
您将如何做?预先谢谢你
PS:请不要建议使用参数化的原始查询:我很好奇,看看是否有可能以适当的方式在Sequelize中做到这一点;)
我的配置:
续集v5 PostgreSQL 12