来自 kusto 函数的动态 return 列
Dynamically return columns from a kusto function
我有一组遥测数据以下面的格式存储在 table 中。让我们将此 table 称为 RawTelemetryData
device_id
TIME
ABC
DEF
GHI
LMN
123
2021-04-20 00:00:00.0000000
1
2
3
4
121
2021-04-20 00:00:00.0000000
1
2
3
4
以上 table 包含每 10 秒来自多个物联网设备的遥测数据。我有一个客户端程序需要根据 device_id.
对不同的列进行 selected
例如。对于device_id123,客户端程序需要ABC,GHI 列。至于 device_id 121 客户端程序期望只有 ABC,DEF。
最初我想编写一个接受 device_id 和要 select 的列的函数。像下面这样。其中第一个参数是设备 ID,第二个参数是要 selected 的列。假设我需要 select ABC,GHI of device id 123 ill call the function like this.
方法一
getDataByDeviceId(123,"ABC,GHI") 此函数应该只投影 ABC 和 GHI
.create-or-alter function with (folder = "getData", skipvalidation = "true") getDataByDeviceId(device_id:int,columns:string) {
}
但我无法让它工作。
方法二
在这种方法中,我在单独的 table 中为每个 device_id 预配置了列。在这种情况下,我尝试编写一个仅接受设备 ID 的函数,以及在下面 table.
中配置的项目列
DEVICE_COLUMN_MAPPING_TABLE
device_id
columns
123
ABC
123
DEF
123
GHI
123
LMN
121
ABC
121
DEF
121
GHI
.create-or-alter function with (folder = "getData", skipvalidation = "true") getDataByDeviceId(device_id:int) {
//program should look at DEVICE_COLUMN_MAPPING_TABLE for colums for this particular device id and project only that.
}
但不幸的是,我无法使它也正常工作。 :(
我想知道是否有可能使上述任何一种方法起作用。如果不行,我只有一个我能想到的解决方案,那就是构造查询基于 device_id 的源程序(一个 java 程序,调用 kusto 函数)的正确项目语句并调用以获取结果。我试图避免这样做,并在 ADX 本身上制定我的所有逻辑。任何其他解决问题的方法也欢迎:)
这是基于您的第二种方法的解决方案:
let device_mappings = datatable(device_id:long, columns_output:string)[
123, "ABC",
123, "GHI",
121, "ABC",
121, "DEF",
122, "LMN"];
let dt = datatable(device_id:long,TIME:datetime,ABC:long,DEF:long,GHI:long,LMN:long)
[123,datetime(2021-04-20 00:00:00.0000000),1,2,3,4,
123,datetime(2021-04-21 00:00:00.0000000),10,20,30,40,
121,datetime(2021-04-20 00:00:00.0000000),1,2,3,4,
122,datetime(2021-04-20 00:00:00.0000000),1,2,3,4];
let func = view(id:long) {
let idKeys = toscalar(device_mappings | where device_id == id | summarize make_set(columns_output));
let otherKeys = toscalar(device_mappings | where device_id != id | summarize make_set(columns_output));
let keysToRemove = set_difference(otherKeys,idKeys);
dt
| where device_id == id
| extend rec = pack_all()
| project filteredRec = bag_remove_keys(rec, keysToRemove)
| evaluate bag_unpack(filteredRec)
};
func(123)
输出:
我有一组遥测数据以下面的格式存储在 table 中。让我们将此 table 称为 RawTelemetryData
device_id | TIME | ABC | DEF | GHI | LMN |
---|---|---|---|---|---|
123 | 2021-04-20 00:00:00.0000000 | 1 | 2 | 3 | 4 |
121 | 2021-04-20 00:00:00.0000000 | 1 | 2 | 3 | 4 |
以上 table 包含每 10 秒来自多个物联网设备的遥测数据。我有一个客户端程序需要根据 device_id.
对不同的列进行 selected例如。对于device_id123,客户端程序需要ABC,GHI 列。至于 device_id 121 客户端程序期望只有 ABC,DEF。
最初我想编写一个接受 device_id 和要 select 的列的函数。像下面这样。其中第一个参数是设备 ID,第二个参数是要 selected 的列。假设我需要 select ABC,GHI of device id 123 ill call the function like this.
方法一
getDataByDeviceId(123,"ABC,GHI") 此函数应该只投影 ABC 和 GHI
.create-or-alter function with (folder = "getData", skipvalidation = "true") getDataByDeviceId(device_id:int,columns:string) {
}
但我无法让它工作。
方法二
在这种方法中,我在单独的 table 中为每个 device_id 预配置了列。在这种情况下,我尝试编写一个仅接受设备 ID 的函数,以及在下面 table.
中配置的项目列DEVICE_COLUMN_MAPPING_TABLE
device_id | columns |
---|---|
123 | ABC |
123 | DEF |
123 | GHI |
123 | LMN |
121 | ABC |
121 | DEF |
121 | GHI |
.create-or-alter function with (folder = "getData", skipvalidation = "true") getDataByDeviceId(device_id:int) {
//program should look at DEVICE_COLUMN_MAPPING_TABLE for colums for this particular device id and project only that.
}
但不幸的是,我无法使它也正常工作。 :(
我想知道是否有可能使上述任何一种方法起作用。如果不行,我只有一个我能想到的解决方案,那就是构造查询基于 device_id 的源程序(一个 java 程序,调用 kusto 函数)的正确项目语句并调用以获取结果。我试图避免这样做,并在 ADX 本身上制定我的所有逻辑。任何其他解决问题的方法也欢迎:)
这是基于您的第二种方法的解决方案:
let device_mappings = datatable(device_id:long, columns_output:string)[
123, "ABC",
123, "GHI",
121, "ABC",
121, "DEF",
122, "LMN"];
let dt = datatable(device_id:long,TIME:datetime,ABC:long,DEF:long,GHI:long,LMN:long)
[123,datetime(2021-04-20 00:00:00.0000000),1,2,3,4,
123,datetime(2021-04-21 00:00:00.0000000),10,20,30,40,
121,datetime(2021-04-20 00:00:00.0000000),1,2,3,4,
122,datetime(2021-04-20 00:00:00.0000000),1,2,3,4];
let func = view(id:long) {
let idKeys = toscalar(device_mappings | where device_id == id | summarize make_set(columns_output));
let otherKeys = toscalar(device_mappings | where device_id != id | summarize make_set(columns_output));
let keysToRemove = set_difference(otherKeys,idKeys);
dt
| where device_id == id
| extend rec = pack_all()
| project filteredRec = bag_remove_keys(rec, keysToRemove)
| evaluate bag_unpack(filteredRec)
};
func(123)
输出: