我可以在 Sequelize.js 中的单个查询中获取 ID 为 1 的类别和该类别的所有子类别吗?
Posted
技术标签:
【中文标题】我可以在 Sequelize.js 中的单个查询中获取 ID 为 1 的类别和该类别的所有子类别吗?【英文标题】:Can I get Category with id 1 and all Subcategories of that Category in a single query in Sequelize.js? 【发布时间】:2020-10-21 14:25:52 【问题描述】:我有以下数据库表:
Table: Categories
Columns: id, name, parent_id
以及以下记录:
1 / Category1 / 0
2 / Category2 / 0
3 / Subcategory1 / 1
4 / Subcategory2 / 1
所以我有 2 个类别 - Category1 和 Category2 以及 Category1 的 2 个子类别 - Subcategory1 和 Subcategory2。
如果 parent_id 字段为 0,则表示该记录是一个类别,如果它不为 0 并且具有另一个类别的 id,则它是该类别的子类别。
现在我得到所有这样的类别:
Category.findAll(
where:
'parent_id': 0
)
.then(result =>
console.log(result)
)
.catch(error =>
console.log(error)
)
但现在我还想以某种方式将类别的子类别包含为对象属性。现在我得到了这个:
[
"id": 1,
"name": "Category1",
"parent_id": 0
]
我想得到这样的东西:
[
"id": 1,
"name": "Category1",
"parent_id": 0,
"subcategories": [
"id": 3,
"name": "Subcategory1",
"parent_id": 1,
,
"id": 4,
"name": "Subcategory2",
"parent_id": 1,
]
]
它类似于预加载,但它就像模型预加载本身。我怎样才能在尽可能少的查询中做到这一点?
【问题讨论】:
【参考方案1】:您需要使用sequelize.define()
创建一个支持您的表格的Model
,在本例中为“类别”
// first define your model, you don't have to define the `id` or `parent_id` as they will be created automatically
const Categories = sequelize.define('categories',
name:
type: DataTypes.STRING(255),
,
,
// use underscores in generated column names
underscored: true,
);
现在为模型创建 parent- 现在您可以使用 在相反的方向,从孩子到父母,或者在这种情况下两者都......// relate a category to its parent=
Categories.belongsTo(Categories,
as: 'parent',
foreignKey: 'parent_id',
targetKey: 'id',
);
// relate parent to child categories
Categories.hasMany(Categories,
as: 'subcategories',
foreignKey: 'parent_id',
);
include
选项传入Model
并指定as
参数以加载正确的关系。传入required: false
以使用左连接,以便在没有子类别的情况下返回结果。// ... your code
// now you can include the subcategories and
// pass in the parent_id into the where clause
const category = await Categories.findOne(
include:
model: Categories,
as: 'subcategories',
required: false,
,
where:
parent_id: 0,
,
);
// if you know the ID you want is 1...
const category = await Categories.findByPk(1,
include:
model: Categories,
as: 'subcategories',
required: false,
,
);
// To get a category and its parent and children...
const categoryWithParentAndSubcategories = await Categories.findByPk(123,
include: [
model: Categories,
as: 'parent',
required: false,
,
model: Categories,
as: 'subcategories',
required: false,
,
],
);
// you can keep going for multiple levels if you want
// To get a category and its grandparent, parent and children...
const categoryWithParentAndSubcategories = await Categories.findByPk(123,
include: [
model: Categories,
as: 'parent',
required: false,
include:
model: Categories,
as: 'parent',
required: false,
,
,
model: Categories,
as: 'subcategories',
required: false,
,
],
);
【讨论】:
以上是关于我可以在 Sequelize.js 中的单个查询中获取 ID 为 1 的类别和该类别的所有子类别吗?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Sequelize.js 和 PostgreSQL 在关联模型上查询 JSONB 字段