Reputation: 169
I am trying to aggregate metric values in specific time windows provided by another table (which captures when a test was executed).
let TestTimes = datatable (start:datetime, end:datetime, testId:string)
[
datetime(2022-09-15T09:29-4), datetime(2022-09-15T13:10-4), "test1",
datetime(2022-09-15T17:51-4), datetime(2022-09-15T22:12-4), "test2",
datetime(2022-09-20T10:50-4), datetime(2022-09-20T15:10-4), "test3",
datetime(2022-09-21T09:00-4), datetime(2022-09-21T14:20-4), "test4",
datetime(2022-09-21T16:00-4), datetime(2022-09-21T20:00-4), "test5",
. . .
];
I create a simple function that accepts a metric table and start/end times
let CountMetric = (T:(Timestamp:datetime, Name:string),startTime:datetime, endTime:datetime, metricName:string) {
T
| where Timestamp between(startTime..endTime)
| where Name == metricName
| summarize count = count()
};
I can call the function in isolation:
CountMetric(MyMetricsTable, datetime(2022-09-15T09:29-4), datetime(2022-09-15T13:10-4), "Metric1");
But, I cannot call it in the context of a query such as running it on the test times table rows:
TestTimes
| extend Metric1Counts = CountMetric(MyMetricsTable, start, end, "Metric1")
The error I get is: Tabular expression is not expected in the current context
Any idea how to solve this simple problem?
Upvotes: 1
Views: 609
Reputation: 44981
That required some acrobatics...
let MyMetricsTable = // data sample generation. Not part of the solution.
materialize
(
range i from 1 to 10000 step 1
| extend Timestamp = datetime(2022-09-10) + 15d*rand()
,Name = strcat("Metric", tostring(toint(rand(3) + 1)))
);
let TestTimes = datatable (start:datetime, end:datetime, testId:string)
[
datetime(2022-09-15T09:29:00-04), datetime(2022-09-15T13:10:00-04), "test1"
,datetime(2022-09-15T17:51:00-04), datetime(2022-09-15T22:12:00-04), "test2"
,datetime(2022-09-20T10:50:00-04), datetime(2022-09-20T15:10:00-04), "test3"
,datetime(2022-09-21T09:00:00-04), datetime(2022-09-21T14:20:00-04), "test4"
,datetime(2022-09-21T16:00:00-04), datetime(2022-09-21T20:00:00-04), "test5"
];
let CountMetric = (T:(Timestamp:datetime, Name:string),startTime:datetime, endTime:datetime, metricName:string)
{
T
| where Timestamp between(startTime..endTime)
| where Name == metricName
| summarize count = count()
};
let CountMetricWrapper = (T:(start:datetime, end:datetime, testId:string), metricsTableName:string, metricName:string)
{
let p_start = toscalar(T | project start);
let p_end = toscalar(T | project end);
let p_testId = toscalar(T | project testId);
CountMetric(table(metricsTableName), p_start, p_end, metricName)
| extend testId = p_testId
};
let TestTimesSerialized =
materialize
(
TestTimes
| serialize
| extend params_batch_id = row_number(0) / 64 + 1
,params_set_id = row_number(0) % 64 + 1
);
union // Each line supports additional 64 parameters sets
(TestTimesSerialized | where params_batch_id == 1 | partition hint.strategy=legacy by params_set_id (invoke CountMetricWrapper("MyMetricsTable", "Metric1")))
,(TestTimesSerialized | where params_batch_id == 2 | partition hint.strategy=legacy by params_set_id (invoke CountMetricWrapper("MyMetricsTable", "Metric1")))
,(TestTimesSerialized | where params_batch_id == 3 | partition hint.strategy=legacy by params_set_id (invoke CountMetricWrapper("MyMetricsTable", "Metric1")))
count | testId |
---|---|
32 | test1 |
33 | test5 |
51 | test4 |
44 | test2 |
45 | test3 |
Upvotes: 1