influxdata / influxdb-client-js

InfluxDB 2.0 JavaScript client
https://influxdata.github.io/influxdb-client-js/
MIT License
327 stars 70 forks source link

Sanitize arrays #217

Closed dferber90 closed 4 years ago

dferber90 commented 4 years ago

Proposal:

A way to sanitize an array of strings so that they can be used in Flux queries.

Current behavior:

Not implemented, or not discovered by me.

Desired behavior:

A way to sanitize strings in an array so I can use that array in contains(set: sanitizedArray, value: foo). Other sanitizations regarding arrays might be missing as well.

Use case:

I have a dynamically generated list of hostnames, for which I'd like to find all matches. To achieve that, I'm trying to use contains to match one of the hostnames.

This is more or less what I got, but the code is not working

const hostnames = ["x", "y"]
 // sanitize inputs
const variables = {
  bucketId: fluxString(pageviewsBucketId),
  start: fluxDateTime(start),
  hostnames: hostnames.map(hostname => fluxString(hostname)),
};

const totalPageViewsQuery = flux`
  from(bucketID: ${variables.bucketId})
  |> range(start: ${variables.start})
  |> filter(fn: (r) => r._measurement == "pageview" and contains(set: ${hostnames}, value: r.hostname))
  |> count()
`;

Alternatives considered:

Chaining the queries together using "or" expressions

const hostnamesExpression = fluxExpression(
  hostnames
    .map((hostname) => flux`r.hostname == ${fluxString(hostname)}`)
    .join(" or ")
);

const totalPageViewsQuery = flux`
  from(bucketID: ${variables.bucketId})
  |> range(start: ${variables.start})
  |> filter(fn: (r) => r._measurement == "pageview" and (${hostnamesExpression}))

Manually creating the list

const hostnamesList = fluxExpression(
  hostnames.map((hostname) => flux`${fluxString(hostname)}`).join(", ")
);

const totalPageViewsQuery = flux`
  from(bucketID: ${variables.bucketId})
  |> range(start: ${variables.start})
  |> filter(fn: (r) => r._measurement == "pageview" and contains(set: [${hostnamesList}], value: r.hostname))
`;

Could you show me the right way to achieve this, or is this a missing feature?

sranka commented 4 years ago

Thank you for posting this issue. Arrays are not supported. And yes, I plan to add them. You can now only simplify the way of how hostnamesList is created:

import {
  flux,
  fluxDuration,
  toFluxValue,
  fluxExpression,
} from '@influxdata/influxdb-client'

const hostnames = ['a', 'b', 'c']
const hostnamesList = fluxExpression(hostnames.map(toFluxValue).join(','))
sranka commented 4 years ago

Arrays will be supported in the next release, you can also use a nightly build (see https://www.npmjs.com/package/@influxdata/influxdb-client) once #219 is merged

dferber90 commented 4 years ago

Thank you for the fast response and impressively fast addition ☺️