Splitting tag value

Hi,
Maybe my approach is completely wrong, but I could find how to do it. I have multiple metrics from machines with following tags: role: “role1,role2”, role: “role1”, role:“role3,role4,role5” etc. and I am trying to process them to yield column with comma separated strings in the tag values like:

table    _value
_result
            role1
            role2
            role3
...        ...

I get the tag values with the following code:

import "influxdata/influxdb/schema"
import "strings"

schema.tagValues(
  bucket: "telegraf", 
  tag: "role",
)
|> some smart filter I could not wrap my head around

I know how to split the resulting string with strings.split(v: r._value, t: “,”), but it seems I can not find the right function to use over the generated array - If I use map it generates n columns with the comma separated values, which is not at all how I need it.
I appreciate if somebody can help me with that.

Hello @Ludmil_Stamboliyski,
Just to verify you want to convert a list to table in Flux programmatically?
I don’t think this is possible.

@scott can you confirm? Thank you.

@Ludmil_Stamboliyski I’m not sure I fully understand what you’re trying to do. Just to clarify, your result of schema.tagValues is similar to this?

_value
role1,role2
role1
role3,role4,role5

I am trying to process them to yield column with comma separated strings in the tag values

This is where I’m not sure exactly what you’re trying to do. When you say “column with comma separated strings,” do you mean a column that stores arrays of strings? If so, that isn’t possible in Flux. Arrays are a composite data type and columns cannot store a composite data type.

Can you explain the problem you’re trying to solve? There is probably another way around it.

Hi Scott - Here is the issue I am trying to solve: I have n servers - some of them have role X, some of them have role Z and some have multiple roles as X, Z and F. I am collecting my data with telegraf - so I have set a tag in global - role where I can store a single value - lets say role: X. I want to pass all roles a particular server has to influx and finally to grafana to use as variable selector in dashboards.

@Ludmil_Stamboliyski Cool, that definitely helps and I think I have a solution for you:

import "array"
import "influxdata/influxdb/schema"
import "strings"

tags = schema.tagValues(bucket: "telegraf", tag: "role")

// Concatenate all string values into a single comma-delimited string
tagsList =
    (tags
        |> reduce(
            identity: {_value: ""},
            fn: (r, accumulator) => ({_value: strings.trimLeft(v: accumulator._value + "," + r._value, cutset: ",")}),
        )
        |> findColumn(fn: (key) => true, column: "_value"))[0]

// Split the tag value string on commas
tagsArr = strings.split(v: tagsList, t: ",")

// Convert each tag array element into a record
// Build a table from the array of records
// Dedup rows in the table
array.from(rows: tagsArr |> array.map(fn: (x) => ({_value: x})))
    |> unique(column: "_value")

Using your sample input data, this returns:

_value
role1
role2
role3

Wow, sincere thanks Scott, that works like a charm!

1 Like