Skip to content

基于关系的聚合

下面以模块test-vona为例,讲解基于关系的聚合的用法

比如,Model User 和 Model Post 是1:n的关系。当我们在查询 User 数据时,可以基于关系查询相应 Post 的聚合数据

动态关系

typescript
class ServiceUser {
  async relationAggregate() {
    const users = await this.scope.model.user.select({
      with: {
        posts: $relationDynamic.hasMany(() => ModelPost, 'userId', {
          aggrs: {
            count: '*',
            sum: 'stars',
          },
        }),
      },
    });
    return users;
  }
}

Vona ORM 自动推断出users的类型

名称说明
with.posts关系名
$relationDynamic.hasMany定义1:n关系
ModelPost目标Model
'userId'外键
aggrs需要聚合的函数和字段。函数:count/sum/avg/min/max。字段:string/string[]

静态关系

1. 定义关系

为了演示起见,新建一个 Model UserStats,定义一个静态关系posts

typescript
@Model({
  entity: EntityUser,
  relations: {
    posts: $relation.hasMany(() => ModelPost, 'userId', {
      aggrs: {
        count: '*',
        sum: 'stars',
      },
    }),
  },
})
class ModelUserStats {}

2. 使用关系

typescript
class ServiceUser {
  async relationAggregate() {
    const users = await this.scope.model.userStats.select({
      include: {
        posts: true,
      },
    });
    return users;
  }
}

Vona ORM 自动推断出users的类型

autoload

也可以将静态关系设为autoload: true,从而实现自动加载,也可以让代码进一步简化

1. 定义关系

diff
@Model({
  entity: EntityUser,
  relations: {
    posts: $relation.hasMany(() => ModelPost, 'userId', {
+     autoload: true,
      aggrs: {
        count: '*',
        sum: 'stars',
      },
    }),
  },
})
class ModelUserStats {}

2. 使用关系

typescript
class ServiceUser {
  async relationAggregate() {
    const users = await this.scope.model.userStats.select();
    return users;
  }
}

基于 MIT 许可发布