Sequelize ORM - 不包括 Left Join
Sequelize ORM - excluding Left Join
我正在使用 Sequelize ORM 构建 Full Stack 社交媒体应用程序。
sequelize: 6.6.5
sequelize-cli: 6.2.0
我的数据库由 tables Users、Posts 和 ReadPosts 构建 - 它有两个外键 - UserId 和 PostId。
该应用程序的一个特点是,用户可以轻松看到 post 尚未被 him/her 阅读的新内容,因此每次用户阅读 post 它在 ReadPost table 中生成一行,由 UserId(读取 post)和 PostId(由用户读取)组成。
我现在要做的是显示所有尚未阅读的 posts,所以这将是某种排除左连接,这将获得所有现有的 posts,并使用给定的 userId 从 ReadPost 中排除那些罐子,但我不知道如何使用 Sequlize 来做到这一点。
阅读Post型号:
module.exports = (sequelize) => {
const readPost = sequelize.define("ReadPost", {})
readPost.associate = models => {
readPost.belongsTo(models.User, {
foreignKey: {
allowNull: false
},
onDelete: "CASCADE",
foreignKeyConstrains: true
})
readPost.belongsTo(models.Post, {
foreignKey: {
allowNull: false
},
onDelete: "CASCADE",
foreignKeyConstrains: true
})
}
return readPost
}
我知道我可以虚拟地做到这一点,只需 运行 在 posts 上找到所有(),而不显示那些尚未阅读的内容,这取决于一些 javascript 标志或简单地 class,但这是我投资组合的一个项目,所以我想正确地完成它。我能帮忙吗?
@阿纳托利
我不得不尝试一下你的代码,因为我使用的是更新版本的 sequelize 并且得到了这样的东西:
exports.showAllUnreadPosts = (req, res, next) => {
db.Post.findAll({
where: {
"ReadPost.id": null,
userId: res.locals.userId //userId extracted from authorization middleware
},
include: [{
model: db.ReadPost,
required: false,
attributes: []
}]
})
它会返回
"error": "Error SequelizeDatabaseError: Unknown column 'Post.ReadPost.id' in 'where clause'"
我试图理解“ReadPost.id”行:null',但据我了解 sql 语法,它将在 Post table?我没有这样的专栏,关系存在于 ReadPost table 中,它收集 userIds 和 postIds,不确定我的实现是否清晰
总而言之 - 我需要从 Post table 中获取所有现有的 posts 并将其与 ReadPost table 进行比较,其中 post存储Id和userId。所以可能我必须 运行 在 Posts 上找到所有,在 ReadPost 上用当前用户 ID 找到所有,并排除所有记录在 Read[=62= 中的那些 postId ] 来自 Post.findAll
查看那些 table 中当前数据的截图:
picture of DB tables
所以基本上我需要 Post.findAll() + ReadPost.findAll() where userId: res.locals.userId and return all posts from Post table 但不存在该 ReadPost 查询。
我希望这样更清楚。
@Anatoly 11/03/22
查询现在有效,但是 returns 只有 posts 没有被任何用户读取(行不存在)并且用户是 post.[=16 的作者=]
我现在设法做的是获取用户已阅读的所有 post(代码如下)。我需要它的对立面(行不存在或存在,但不使用此 userId)
因此,从存在的所有 post 中,Select 那些被用户读取的,并从数据库中的所有 post 中排除其他那些
exports.showAllUnreadPosts = (req, res, next) => {
db.Post.findAll({
where: {
'$readposts.UserId$': res.locals.userId // User Id extracted from auth middleware
},
include: [{
model: db.ReadPost,
required: false,
attributes: [],
}]
}).then(unreadPosts => {
res.status(200).json(unreadPosts);
})
.catch((error) => {
res.status(500).json({
error: 'Error ' + error
})
})
}
能否请教一下?
您可以通过添加条件 Readpost.id is null
查询所有在 ReadPost 中没有 link 记录的帖子,如下所示:
const unreadPosts = await Post.findAll({
where: {
'$ReadPost.id$': null,
userId: userId
},
include: [{
model: ReadPost,
required: false,
attributes: [],
where: {
UserId: userId
},
}]
})
当然,您需要添加从 Post
到 ReadPost
的关联:
Post.hasMany(ReadPost, <some_options_here>);
是的,看来我在@Anatoly 的大力帮助下找到了解决方案。
我不确定这是否是个好主意,因为我在 THEN 块中添加了第二种方法,我很高兴收到任何反馈。
exports.showAllUnreadPosts = (req, res, next) => {
db.Post.findAll({
where: {
'$readposts.UserId$': res.locals.userId // User Id extracted from auth middleware
},
attributes: ['id'],
include: [{
model: db.ReadPost,
required: false,
attributes: [],
}]
}).then(readPosts => {
db.Post.findAll({
where: {
id: {
[Op.not]: (() => readPosts.map(readPost => readPost.id))()
}
}
})
.then((unreadPosts) => {
res.status(200).json(unreadPosts);
})
.catch((error) => {
res.status(500).json({
error: 'Error' + error
})
})
})
.catch((error) => {
res.status(500).json({
error: 'Error ' + error
})
})
}
首先有一个方法,在readposttable和returns[=中检查所有已经被用户读过的post 18=] ID。其次在 THEN 块中,它获取数据库中所有现有的 posts,并从上述方法中排除具有 id 的那些(通过 [OP.not])。我希望它有意义,但不确定性能。
我正在使用 Sequelize ORM 构建 Full Stack 社交媒体应用程序。
sequelize: 6.6.5
sequelize-cli: 6.2.0
我的数据库由 tables Users、Posts 和 ReadPosts 构建 - 它有两个外键 - UserId 和 PostId。
该应用程序的一个特点是,用户可以轻松看到 post 尚未被 him/her 阅读的新内容,因此每次用户阅读 post 它在 ReadPost table 中生成一行,由 UserId(读取 post)和 PostId(由用户读取)组成。
我现在要做的是显示所有尚未阅读的 posts,所以这将是某种排除左连接,这将获得所有现有的 posts,并使用给定的 userId 从 ReadPost 中排除那些罐子,但我不知道如何使用 Sequlize 来做到这一点。
阅读Post型号:
module.exports = (sequelize) => {
const readPost = sequelize.define("ReadPost", {})
readPost.associate = models => {
readPost.belongsTo(models.User, {
foreignKey: {
allowNull: false
},
onDelete: "CASCADE",
foreignKeyConstrains: true
})
readPost.belongsTo(models.Post, {
foreignKey: {
allowNull: false
},
onDelete: "CASCADE",
foreignKeyConstrains: true
})
}
return readPost
}
我知道我可以虚拟地做到这一点,只需 运行 在 posts 上找到所有(),而不显示那些尚未阅读的内容,这取决于一些 javascript 标志或简单地 class,但这是我投资组合的一个项目,所以我想正确地完成它。我能帮忙吗?
@阿纳托利
我不得不尝试一下你的代码,因为我使用的是更新版本的 sequelize 并且得到了这样的东西:
exports.showAllUnreadPosts = (req, res, next) => {
db.Post.findAll({
where: {
"ReadPost.id": null,
userId: res.locals.userId //userId extracted from authorization middleware
},
include: [{
model: db.ReadPost,
required: false,
attributes: []
}]
})
它会返回
"error": "Error SequelizeDatabaseError: Unknown column 'Post.ReadPost.id' in 'where clause'"
我试图理解“ReadPost.id”行:null',但据我了解 sql 语法,它将在 Post table?我没有这样的专栏,关系存在于 ReadPost table 中,它收集 userIds 和 postIds,不确定我的实现是否清晰
总而言之 - 我需要从 Post table 中获取所有现有的 posts 并将其与 ReadPost table 进行比较,其中 post存储Id和userId。所以可能我必须 运行 在 Posts 上找到所有,在 ReadPost 上用当前用户 ID 找到所有,并排除所有记录在 Read[=62= 中的那些 postId ] 来自 Post.findAll
查看那些 table 中当前数据的截图: picture of DB tables
所以基本上我需要 Post.findAll() + ReadPost.findAll() where userId: res.locals.userId and return all posts from Post table 但不存在该 ReadPost 查询。
我希望这样更清楚。
@Anatoly 11/03/22 查询现在有效,但是 returns 只有 posts 没有被任何用户读取(行不存在)并且用户是 post.[=16 的作者=]
我现在设法做的是获取用户已阅读的所有 post(代码如下)。我需要它的对立面(行不存在或存在,但不使用此 userId)
因此,从存在的所有 post 中,Select 那些被用户读取的,并从数据库中的所有 post 中排除其他那些
exports.showAllUnreadPosts = (req, res, next) => {
db.Post.findAll({
where: {
'$readposts.UserId$': res.locals.userId // User Id extracted from auth middleware
},
include: [{
model: db.ReadPost,
required: false,
attributes: [],
}]
}).then(unreadPosts => {
res.status(200).json(unreadPosts);
})
.catch((error) => {
res.status(500).json({
error: 'Error ' + error
})
})
}
能否请教一下?
您可以通过添加条件 Readpost.id is null
查询所有在 ReadPost 中没有 link 记录的帖子,如下所示:
const unreadPosts = await Post.findAll({
where: {
'$ReadPost.id$': null,
userId: userId
},
include: [{
model: ReadPost,
required: false,
attributes: [],
where: {
UserId: userId
},
}]
})
当然,您需要添加从 Post
到 ReadPost
的关联:
Post.hasMany(ReadPost, <some_options_here>);
是的,看来我在@Anatoly 的大力帮助下找到了解决方案。
我不确定这是否是个好主意,因为我在 THEN 块中添加了第二种方法,我很高兴收到任何反馈。
exports.showAllUnreadPosts = (req, res, next) => {
db.Post.findAll({
where: {
'$readposts.UserId$': res.locals.userId // User Id extracted from auth middleware
},
attributes: ['id'],
include: [{
model: db.ReadPost,
required: false,
attributes: [],
}]
}).then(readPosts => {
db.Post.findAll({
where: {
id: {
[Op.not]: (() => readPosts.map(readPost => readPost.id))()
}
}
})
.then((unreadPosts) => {
res.status(200).json(unreadPosts);
})
.catch((error) => {
res.status(500).json({
error: 'Error' + error
})
})
})
.catch((error) => {
res.status(500).json({
error: 'Error ' + error
})
})
}
首先有一个方法,在readposttable和returns[=中检查所有已经被用户读过的post 18=] ID。其次在 THEN 块中,它获取数据库中所有现有的 posts,并从上述方法中排除具有 id 的那些(通过 [OP.not])。我希望它有意义,但不确定性能。