Slate中TypeScript函数过滤对象获取属性最大值问题排查
问题:对象集过滤获取数值列最大值的相关问题
初始代码与问题
需要对对象集过滤后获取lngPlanningNumber列的最大数值,初始代码返回结果包含该字段为NULL的对象,需要过滤空值:
@Function() public async largestNumber(): Promise<Long> { const objResult = Objects.search() .dataMain() .filter(data_column => data_column.lngPlanningNumber.range. ) .gt(100) .take(1); return objResult.max(); }
调试过程报错
尝试过滤空值时触发类型错误:
Property 'isNotNull' does not exist on type 'INumericPropertyFilter'.
对应错误代码:
.filter(data_column => data_column.lngPlanningNumber.isNotNull()) // 过滤NULL值
调用take方法时触发类型错误:
Property 'take' does not exist on type 'Promise<number | null>'.
对应错误代码:
.take(1);
调整后代码与剩余疑问
调整代码后如下:
@Function() @Edits(XYZ) public async fctLargestNumber(): Promise<XYZ[]> { const maxObject = Objects.search() .xYZ() // .groupBy(e => e.lngPlanningNumber.topValues()) // .segmentBy(e => e.lngPlanningNumber.topValues()) // .filter(data_column => data_column.lngPlanningNumber.byIRanges({ min: 100000, max: 999999 })) .orderBy(data_column => data_column.lngPlanningNumber.desc()) .takeAsync(1) //.valueOf(); return maxObject; }
当前返回结果:
[ {"typeId":"my-collection","primaryKey":{"id_pk":"ee1b1ac1-008b-479b-a748-01e8702927c9"}} ]
待解决疑问:
- 如何提取返回结果中的primaryKey值?
- 如何查询该主键id对应的
lngPlanningNumber列的整数值? - 返回的Promise类型相关逻辑不清晰。
解答
报错根因说明
- 链式调用位置错误:
.gt()等数值过滤方法必须写在.filter()回调内部,直接挂载在search链式调用后会丢失上下文触发类型错误。 - API使用错误:数值类型属性没有
isNotNull()方法,NULL值不会参与数值范围匹配,直接配置数值范围即可自动过滤空值;max()属于聚合方法,调用后直接返回Promise包裹的聚合结果,后续不能再接.take()方法。 - Promise使用错误:所有异步查询方法返回的Promise对象必须用
await解析后,才能访问结果的属性/方法,否则会触发类型不存在的报错。
最优实现:直接聚合取最大值
不需要排序拉取对象,直接用聚合接口查询最大值,性能更高,自动跳过NULL值:
@Function() public async largestNumber(): Promise<number | null> { // 如需保留大于100的过滤逻辑,把range.gte(-Infinity)改成range.gt(100)即可 const maxValue = await Objects.search() .dataMain() .filter(col => col.lngPlanningNumber.range.gte(-Infinity)) .aggregate(col => col.lngPlanningNumber.max()) return maxValue; }
排序取数方案的问题处理
如果需要拿到最大值对应的完整对象,用排序+takeAsync的方案时按以下方式调整:
- 提取主键与目标字段值:
takeAsync默认只返回主键和typeId,需要在查询参数中指定要拉取的属性,解析结果后直接取对应属性即可:
const resList = await Objects.search() .xYZ() .orderBy(col => col.lngPlanningNumber.desc()) .takeAsync(1, { select: ["lngPlanningNumber"] }) // 第二个参数指定要返回的属性 const firstItem = resList[0]; // 提取主键 const pkValue = firstItem.primaryKey.id_pk; // 获取lngPlanningNumber的整数值 const targetNum = firstItem.lngPlanningNumber;
- Promise类型说明:所有带
Async后缀的查询方法、聚合方法都是异步执行,返回Promise类型,必须加await等待结果返回后再做后续操作,不需要额外手动解析Promise内部结构。
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

