[英]Include child records count in the parent record attributes list without fetching all child records
I have setup a very basic minified playground for sequelize experiements to learn how it behaves on association records fetch.我已经设置了一个非常基本的小型游乐场,用于后续实验,以了解它在关联记录获取时的行为。 But i am not able to achieve the desired output.
但我无法达到预期的输出。
Reproduceable Code可重现的代码
const Sequelize = require('sequelize');
const { fn } = Sequelize;
const sequelize = new Sequelize('playground', 'postgres', 'postgres', {
host: 'localhost',
dialect: 'postgres',
pool: {
max: 9,
min: 0,
idle: 10000
}
});
const Posts = sequelize.define('posts', {
id: {
type: Sequelize.INTEGER,
primaryKey: true
},
title: {
type: Sequelize.STRING
},
content: {
type: Sequelize.STRING
}
},
{
freezeTableName: true,
timestamps: false
}
);
const Comments = sequelize.define('comments', {
id: {
type: Sequelize.INTEGER,
primaryKey: true
},
postId: {
type: Sequelize.INTEGER,
references: {
model: 'posts',
key: 'id'
}
},
comment: {
type: Sequelize.STRING
}
},
{
freezeTableName: true,
timestamps: false
}
);
Posts.hasMany(Comments, {
foreignKey: 'postId'
})
let criteria = {
group: ['posts.id', 'comments.id'],
attributes: [
[fn('count', 'comments.id'), 'TotalComments']
],
include: [
{
model: Comments,
}
]
}
Posts.findAll(criteria).then(posts =>{
console.dir(JSON.parse(JSON.stringify(posts)), {depth: null, colors: true});
});
Problem Encountering遇到问题
The problem is straight forward i want to add the child records count in the parent attributes eg the count of all comments in the every post returned, but the output i am getting is returning a fix count which is 1. I can simply iterate all posts and set TotalComments by reading the total length of comments included, but i want to do this using sequelize query, because that way i can apply some filter eg posts with comments between 6 to 10问题很简单,我想在父属性中添加子记录计数,例如返回的每个帖子中所有评论的计数,但我得到的输出是返回一个固定计数,即 1。我可以简单地迭代所有帖子并通过读取包含的评论的总长度来设置 TotalComments,但我想使用 sequelize 查询来做到这一点,因为这样我可以应用一些过滤器,例如评论在 6 到 10 之间的帖子
Output Shown显示的输出
[
{
id: 101,
title: 'The revolution in brain',
TotalComments: '1', //this count is not matched with below included comments count
comments: [
{ id: 15, postId: 101, comment: 'It helped me a lot' },
{ id: 13, postId: 101, comment: 'very disapointing' },
{ id: 12, postId: 101, comment: 'welldone' },
{ id: 14, postId: 101, comment: 'This post sucks' }
]
},
{
id: 102,
title: 'Making your hands dirty on Java',
TotalComments: '1',
comments: []
},
{
id: 100,
title: 'Earlier models of medical surgery',
TotalComments: '1',
comments: [
{ id: 10, postId: 100, comment: 'Appreciated your work' },
{ id: 11, postId: 100, comment: 'good' }
]
}
]
Output Desired所需输出
[
{
id: 101,
title: 'The revolution in brain',
TotalComments: 4,
comments: [
{ id: 15, postId: 101, comment: 'It helped me a lot' },
{ id: 13, postId: 101, comment: 'very disapointing' },
{ id: 12, postId: 101, comment: 'welldone' },
{ id: 14, postId: 101, comment: 'This post sucks' }
]
},
{
id: 102,
title: 'Making your hands dirty on Java',
TotalComments: 0,
comments: []
},
{
id: 100,
title: 'Earlier models of medical surgery',
TotalComments: 2,
comments: [
{ id: 10, postId: 100, comment: 'Appreciated your work' },
{ id: 11, postId: 100, comment: 'good' }
]
}
]
Generated SQL生成的 SQL
SELECT "posts"."id", "posts"."title", count('comments.id') AS "TotalComments", "comments"."id" AS "comments.id", "comments"."postId" AS "comments.postId", "comments"."comment" AS "comments.comment" FROM "posts" AS "posts" LEFT OUTER JOIN "comments" AS "comments" ON "posts"."id" = "comments"."postId" GROUP BY "posts"."id", "comments"."id";
I solved the issue my self after a lot of searching, i hope it will help every body else if they encounter similar issue, basically i used the sequelize literal to insert some raw query to address the problem, the modified query criteria example is following经过大量搜索,我自己解决了这个问题,如果遇到类似的问题,我希望它能帮助其他所有人,基本上我使用 sequelize 文字插入一些原始查询来解决问题,修改后的查询条件示例如下
let criteria = {
group: ['posts.id', 'comments.id'],
attributes: [
'id',
'title',
[literal('(select count(comments.id) from comments where "comments"."postId" = "posts"."id")'), 'TotalComments']
],
include: [
{
model: Comments,
}
]
}
Posts.findAll(criteria).then(posts =>{
console.dir(JSON.parse(JSON.stringify(posts)), {depth: null, colors: true});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.