我一直在尝试创建一个带有自连接的树表(mssql,sequelize)。
\+----+--------------+--------+
| id | name | parent |
\+----+--------------+--------+
| 1 | ABC | null |
| 2 | DEF | null |
| 3 | GHI | 2 |
| 4 | JKL | 3 |
| 5 | MNO | 4 |
\+----+--------------+--------+
我需要以下结果。请注意,深度是无限的。
[
{
"id": 1,
"name": "ABC",
"children": null
},
{
"id": 2,
"name": "DEF",
"children": [
{
"id": 3,
"name": "GHI",
"children": [
{
"id": 4,
"name": "JKL",
"children": [ {
"id": 5,
"name": "MNO",
"children": null
},]
},
]
},
]
}
]
下面是我的模型
@Table()
export class AccHead extends Model {
@Column({
type: DataType.BIGINT,
primaryKey: true,
autoIncrement: true,
})
id: number;
name: string;
@ForeignKey(() => AccHead)
@Column({
type: DataType.BIGINT,
onDelete: 'NO ACTION',
})
parentId: number;
@BelongsTo(() => AccHead, { foreignKey: 'parentId' })
parent: AccHead;
@HasMany(() => AccHead, { foreignKey: 'parentId' })
children: AccHead[];
}
我尝试了下面的查询,但它只限于我包含模型的级别,我想递归地包含子项: (原表超过150k+条记录,需要优化查询)
const hierarchicalData = await AccHead.findAll({
where: {
parentId: null, // Retrieve top-level categories
},
include: [
{
model: AccHead,
as: 'children',
where: {
parentId: { [Op.ne]: null },
},
include: [
{
model: AccHead,
as: 'children',
include: [
{
model: AccHead,
as: 'children',
},
],
},
],
},
],
});
我找到的最佳解决方案之一是
sequelize-hierarchy Documentation 这正是我所需要的。它有自己的函数来处理树操作。
const Folder = sequelize.define('folder', { name: Sequelize.STRING });
Folder.isHierarchy();
或者
const Folder = sequelize.define('folder', {
name: Sequelize.STRING
}, {
hierarchy: true
});
但是我无法在 Nest Js 中实现它,因为该文档是用于 Node.js 中的续集。 有人可以帮我在 Nest js 中做同样的事情,或者任何其他更好的方法吗?
import {
Table,
Column,
Model,
DataType,
ForeignKey,
BelongsTo,
} from 'sequelize-typescript';
import { Hierarchy } from 'sequelize-hierarchy';
@Table
@Hierarchy({
foreignKey: 'parentId',
levelFieldName: 'level',
structure: 'tree',
})
export class Category extends Model<Category> {
@Column({
type: DataType.STRING,
allowNull: false,
})
name: string;
@Column({
type: DataType.INTEGER,
allowNull: true,
})
parentId: number;
@BelongsTo(() => Category)
parent: Category;
}
Try This, Answer by Chat Gpt