fix(cube): 为关联表添加主键和维度定义
修复所有cube文件中缺失的主键和维度定义问题,确保每个关联表都有明确的主键和必要的外键维度。这些修改解决了Cube.js编译错误并支持正确的聚合操作。
This commit is contained in:
parent
dacefd730a
commit
b79384d2e1
|
|
@ -1,37 +1,54 @@
|
||||||
## 实施计划
|
## 修复计划
|
||||||
|
|
||||||
### 1. 问题分析
|
### 问题分析
|
||||||
- 错误:ER_CANT_AGGREGATE_2COLLATIONS - 字符集排序规则不匹配
|
- 所有报错的cube文件都缺少主键定义
|
||||||
- 原因:order_item表使用utf8mb4_0900_ai_ci,product表使用utf8mb4_unicode_ci
|
- 所有cube的dimensions数组为空
|
||||||
- 解决方案:在JOIN条件中显式指定排序规则,或修改JOIN方式
|
- 当cube定义了join时,Cube.js要求必须有一个主键
|
||||||
|
|
||||||
### 2. 调整join配置
|
### 修复策略
|
||||||
在order_item.yml中修改与product的join配置,添加字符集转换函数,确保排序规则匹配:
|
为每个cube添加适当的主键和维度定义。由于这些都是关联表(junction tables),我将:
|
||||||
|
1. 添加id字段作为主键(如果表中存在)
|
||||||
|
2. 添加表中的外键字段作为维度
|
||||||
|
3. 确保每个cube都有明确的primary_key定义
|
||||||
|
|
||||||
```yaml
|
### 具体修复文件
|
||||||
joins:
|
|
||||||
- name: product
|
|
||||||
sql: "CONVERT({product.siteSkus} USING utf8mb4) COLLATE utf8mb4_unicode_ci LIKE CONCAT('%', {CUBE}.sku, '%')"
|
|
||||||
relationship: many_to_one
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 优化join逻辑
|
#### 1. product_attributes_dict_item.yml
|
||||||
考虑到siteSkus可能是JSON格式或包含多个SKU,使用更可靠的JSON函数处理(如果数据库支持):
|
- 添加id、dictItemId、productId作为维度
|
||||||
|
- 将id设为主键
|
||||||
|
|
||||||
```yaml
|
#### 2. product_v2_attributes_dict_item.yml
|
||||||
joins:
|
- 添加id、dictItemId、productV2Id作为维度
|
||||||
- name: product
|
- 将id设为主键
|
||||||
sql: "JSON_CONTAINS({product.siteSkus}, JSON_QUOTE({CUBE}.sku))"
|
|
||||||
relationship: many_to_one
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. 实施步骤
|
#### 3. site_stock_points_stock_point.yml
|
||||||
1. 编辑order_item.yml文件,修改product join配置
|
- 添加id、siteId、stockPointId作为维度
|
||||||
2. 选择合适的join条件:
|
- 将id设为主键
|
||||||
- 如果siteSkus是逗号分隔列表:使用CONVERT函数转换排序规则
|
|
||||||
- 如果siteSkus是JSON数组:使用JSON_CONTAINS函数
|
|
||||||
3. 验证查询文件order_item_product_by_sku_quantity_sum.json能够正确执行
|
|
||||||
4. 确保查询结果显示product相关信息和对应的销售数量
|
|
||||||
|
|
||||||
### 5. 预期效果
|
#### 4. site_v2_stock_points_stock_point.yml
|
||||||
添加正确的join后,查询将能够关联order_item和product的数据,计算出每个product的实际销售数量(基于order_item.quantity)
|
- 添加id、siteV2Id、stockPointId作为维度
|
||||||
|
- 将id设为主键
|
||||||
|
|
||||||
|
#### 5. site_areas_area.yml
|
||||||
|
- 添加id、siteId、areaId作为维度
|
||||||
|
- 将id设为主键
|
||||||
|
|
||||||
|
#### 6. site_v2_areas_area.yml
|
||||||
|
- 添加id、siteV2Id、areaId作为维度
|
||||||
|
- 将id设为主键
|
||||||
|
|
||||||
|
#### 7. stock_point_areas_area.yml
|
||||||
|
- 添加id、stockPointId、areaId作为维度
|
||||||
|
- 将id设为主键
|
||||||
|
|
||||||
|
### 修复后效果
|
||||||
|
- 解决编译错误,所有cube都有正确的主键定义
|
||||||
|
- 保持现有的join关系不变
|
||||||
|
- 允许在查询中使用这些cube的维度进行分析
|
||||||
|
- 支持正确的聚合操作
|
||||||
|
|
||||||
|
### 实施步骤
|
||||||
|
1. 依次编辑每个yml文件
|
||||||
|
2. 为每个cube添加dimensions配置
|
||||||
|
3. 为每个cube设置primary_key
|
||||||
|
4. 保存并验证修复效果
|
||||||
|
|
@ -16,7 +16,19 @@ cubes:
|
||||||
sql: "{CUBE}.`productId` = {product.id}"
|
sql: "{CUBE}.`productId` = {product.id}"
|
||||||
relationship: many_to_one
|
relationship: many_to_one
|
||||||
|
|
||||||
dimensions: []
|
dimensions:
|
||||||
|
- name: id
|
||||||
|
sql: id
|
||||||
|
type: number
|
||||||
|
primary_key: true
|
||||||
|
|
||||||
|
- name: dict_item_id
|
||||||
|
sql: "{CUBE}.`dictItemId`"
|
||||||
|
type: number
|
||||||
|
|
||||||
|
- name: product_id
|
||||||
|
sql: "{CUBE}.`productId`"
|
||||||
|
type: number
|
||||||
|
|
||||||
measures:
|
measures:
|
||||||
- name: count
|
- name: count
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,19 @@ cubes:
|
||||||
sql: "{CUBE}.`productV2Id` = {product_v2.id}"
|
sql: "{CUBE}.`productV2Id` = {product_v2.id}"
|
||||||
relationship: many_to_one
|
relationship: many_to_one
|
||||||
|
|
||||||
dimensions: []
|
dimensions:
|
||||||
|
- name: id
|
||||||
|
sql: id
|
||||||
|
type: number
|
||||||
|
primary_key: true
|
||||||
|
|
||||||
|
- name: dict_item_id
|
||||||
|
sql: "{CUBE}.`dictItemId`"
|
||||||
|
type: number
|
||||||
|
|
||||||
|
- name: product_v2_id
|
||||||
|
sql: "{CUBE}.`productV2Id`"
|
||||||
|
type: number
|
||||||
|
|
||||||
measures:
|
measures:
|
||||||
- name: count
|
- name: count
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,19 @@ cubes:
|
||||||
sql: "{CUBE}.`siteId` = {site.id}"
|
sql: "{CUBE}.`siteId` = {site.id}"
|
||||||
relationship: many_to_one
|
relationship: many_to_one
|
||||||
|
|
||||||
dimensions: []
|
dimensions:
|
||||||
|
- name: id
|
||||||
|
sql: id
|
||||||
|
type: number
|
||||||
|
primary_key: true
|
||||||
|
|
||||||
|
- name: site_id
|
||||||
|
sql: "{CUBE}.`siteId`"
|
||||||
|
type: number
|
||||||
|
|
||||||
|
- name: area_id
|
||||||
|
sql: "{CUBE}.`areaId`"
|
||||||
|
type: number
|
||||||
|
|
||||||
measures:
|
measures:
|
||||||
- name: count
|
- name: count
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,19 @@ cubes:
|
||||||
sql: "{CUBE}.`stockPointId` = {stock_point.id}"
|
sql: "{CUBE}.`stockPointId` = {stock_point.id}"
|
||||||
relationship: many_to_one
|
relationship: many_to_one
|
||||||
|
|
||||||
dimensions: []
|
dimensions:
|
||||||
|
- name: id
|
||||||
|
sql: id
|
||||||
|
type: number
|
||||||
|
primary_key: true
|
||||||
|
|
||||||
|
- name: site_id
|
||||||
|
sql: "{CUBE}.`siteId`"
|
||||||
|
type: number
|
||||||
|
|
||||||
|
- name: stock_point_id
|
||||||
|
sql: "{CUBE}.`stockPointId`"
|
||||||
|
type: number
|
||||||
|
|
||||||
measures:
|
measures:
|
||||||
- name: count
|
- name: count
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,19 @@ cubes:
|
||||||
sql: "{CUBE}.`siteV2Id` = {site_v2.id}"
|
sql: "{CUBE}.`siteV2Id` = {site_v2.id}"
|
||||||
relationship: many_to_one
|
relationship: many_to_one
|
||||||
|
|
||||||
dimensions: []
|
dimensions:
|
||||||
|
- name: id
|
||||||
|
sql: id
|
||||||
|
type: number
|
||||||
|
primary_key: true
|
||||||
|
|
||||||
|
- name: site_v2_id
|
||||||
|
sql: "{CUBE}.`siteV2Id`"
|
||||||
|
type: number
|
||||||
|
|
||||||
|
- name: area_id
|
||||||
|
sql: "{CUBE}.`areaId`"
|
||||||
|
type: number
|
||||||
|
|
||||||
measures:
|
measures:
|
||||||
- name: count
|
- name: count
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,19 @@ cubes:
|
||||||
sql: "{CUBE}.`stockPointId` = {stock_point.id}"
|
sql: "{CUBE}.`stockPointId` = {stock_point.id}"
|
||||||
relationship: many_to_one
|
relationship: many_to_one
|
||||||
|
|
||||||
dimensions: []
|
dimensions:
|
||||||
|
- name: id
|
||||||
|
sql: id
|
||||||
|
type: number
|
||||||
|
primary_key: true
|
||||||
|
|
||||||
|
- name: site_v2_id
|
||||||
|
sql: "{CUBE}.`siteV2Id`"
|
||||||
|
type: number
|
||||||
|
|
||||||
|
- name: stock_point_id
|
||||||
|
sql: "{CUBE}.`stockPointId`"
|
||||||
|
type: number
|
||||||
|
|
||||||
measures:
|
measures:
|
||||||
- name: count
|
- name: count
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,19 @@ cubes:
|
||||||
sql: "{CUBE}.`stockPointId` = {stock_point.id}"
|
sql: "{CUBE}.`stockPointId` = {stock_point.id}"
|
||||||
relationship: many_to_one
|
relationship: many_to_one
|
||||||
|
|
||||||
dimensions: []
|
dimensions:
|
||||||
|
- name: id
|
||||||
|
sql: id
|
||||||
|
type: number
|
||||||
|
primary_key: true
|
||||||
|
|
||||||
|
- name: stock_point_id
|
||||||
|
sql: "{CUBE}.`stockPointId`"
|
||||||
|
type: number
|
||||||
|
|
||||||
|
- name: area_id
|
||||||
|
sql: "{CUBE}.`areaId`"
|
||||||
|
type: number
|
||||||
|
|
||||||
measures:
|
measures:
|
||||||
- name: count
|
- name: count
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"dimensions": ["product.sku"],
|
"dimensions": ["product.sku"],
|
||||||
"measures": ["order_item.quantity"],
|
"measures": ["order_item.quantity","product.siteskus"],
|
||||||
"order": {
|
"order": {
|
||||||
"order_item.quantity": "desc"
|
"order_item.quantity": "desc"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue