如何按包含的实体搜索/选择,但将所有相关实体包含到结果集中
Posted
技术标签:
【中文标题】如何按包含的实体搜索/选择,但将所有相关实体包含到结果集中【英文标题】:How to search for/select by included entity but include all related entities into result set 【发布时间】:2020-11-10 07:34:42 【问题描述】:在我的应用程序中,我使用的是 sequelize ORM。有几个实体:Tool
可以有 Tags
和 Categories
。
现在我想搜索所有具有特定Tag
的Tool
s,但我想包括该工具的所有相关Tag
s(不仅仅是特定的)。如果我现在将where
语句放入包含中,则只有指定的Tag
s 包含在结果集中(请参阅[2]
)。我试图在外部 where 语句中限制 Tag
s(参见 [1]
),但这也无济于事。
示例
工具A
具有标签t1
、t2
和t3
。现在我想搜索所有具有标签t3
的工具,但结果集应包含所有三个标签。
预期结果:
Tool A
\
- Tag t1
- Tag t2
- Tag t3
db.Tool.scope('published').findAll(
where: '$tool.tag.name$': filter.tag , // [1] Does not work
include: [
model: db.User,
attributes: ['id', 'username']
,
model: db.Tag,
attributes: ['name'],
through: attributes: [] ,
// [2] Would limit the result specified tag
// where:
// name:
// [Op.and]: filter.tag
//
//
,
model: db.Category,
attributes: ['id', 'name', 'views'],
through: attributes: ['relevance'] ,
where:
id:
[Op.and]: filter.category
],
where:
title:
[Op.like]: `%$filter.term%`,
,
attributes: ['id', 'title', 'description', 'slug', 'docLink', 'vendor', 'vendorLink', 'views', 'status', 'createdAt'],
order: [['title', 'ASC'], [db.Tag, 'name', 'ASC']]
)
我知道我可以通过首先通过标签执行选择来执行此操作(db.Tag.findAll()
而不是db.Tool.findAll()
;I've already done this elsewhere in my project),但同时我也希望能够通过另一个过滤实体 (Category
) 以同样的方式。所以Tool.findAll()
应该是起点。
任何帮助表示赞赏!
【问题讨论】:
【参考方案1】:首先,您的***查询中有两个 where 子句:
where: '$tool.tag.name$': filter.tag , // [1] Does not work
// ...
where:
title:
[Op.like]: `%$filter.term%`,
,
我认为您最好的方法是在 WHERE 子句中使用 literal
子查询。基本上我们想找到所有具有正确标签并包含filter.term
的工具的ID。
WHERE 的子查询部分看起来像...
SELECT ToolId FROM ToolTags WHERE TagId='t2';
受这篇文章Sequelize - subquery in where clause的子查询解决方案的启发
// assuming your join table is named 'ToolTags' in the database--we need the real table name not the model name
const tempSQL = sequelize.dialect.QueryGenerator.selectQuery('ToolTags',
attributes: ['ToolId'],
where:
TagId: filter.tag
)
.slice(0,-1); // to remove the ';' from the end of the SQL
db.Tool.scope('published').findAll(
where:
title:
[Op.like]: `%$filter.term%`,
,
id:
[Op.In]: sequelize.literal(`($tempSQL)`)
,
include: [
model: db.User,
attributes: ['id', 'username']
,
model: db.Tag,
attributes: ['name'],
through: attributes: [] ,
,
//
// model: db.Category,
// attributes: ['id', 'name', 'views'],
// through: attributes: ['relevance'] ,
// where:
// id:
// [Op.and]: filter.category
//
//
//
],
attributes: ['id', 'title', 'description', 'slug', 'docLink', 'vendor', 'vendorLink', 'views', 'status', 'createdAt'],
order: [['title', 'ASC'], [db.Tag, 'name', 'ASC']]
)
我暂时注释掉了您的类别加入。我认为您应该在向查询中添加更多内容之前尝试隔离标签的解决方案。
【讨论】:
这看起来很有希望,如果有帮助,我会研究一下并检查这个答案。谢谢!以上是关于如何按包含的实体搜索/选择,但将所有相关实体包含到结果集中的主要内容,如果未能解决你的问题,请参考以下文章