Merge pull request #1994 from influxdata/flux-0.99

Flux 0.99
pull/1995/head
Scott Anderson 2020-12-15 21:51:04 -07:00 committed by GitHub
commit a14a33575e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 452 additions and 1067 deletions

View File

@ -14,124 +14,4 @@ related:
- /influxdb/cloud/reference/flux/stdlib/built-in/transformations/filter
---
This guide walks through the basics of using Flux to query data from InfluxDB.
Every Flux query needs the following:
1. [A data source](#1-define-your-data-source)
2. [A time range](#2-specify-a-time-range)
3. [Data filters](#3-filter-your-data)
## 1. Define your data source
Flux's [`from()`](/influxdb/cloud/reference/flux/stdlib/built-in/inputs/from) function defines an InfluxDB data source.
It requires a [`bucket`](/influxdb/cloud/reference/flux/stdlib/built-in/inputs/from#bucket) parameter.
The following examples use `example-bucket` as the bucket name.
```js
from(bucket:"example-bucket")
```
## 2. Specify a time range
Flux requires a time range when querying time series data.
"Unbounded" queries are very resource-intensive and as a protective measure,
Flux will not query the database without a specified range.
Use the pipe-forward operator (`|>`) to pipe data from your data source into the [`range()`](/influxdb/cloud/reference/flux/stdlib/built-in/transformations/range)
function, which specifies a time range for your query.
It accepts two parameters: `start` and `stop`.
Ranges can be **relative** using negative [durations](/influxdb/cloud/reference/flux/language/lexical-elements#duration-literals)
or **absolute** using [timestamps](/influxdb/cloud/reference/flux/language/lexical-elements#date-and-time-literals).
###### Example relative time ranges
```js
// Relative time range with start only. Stop defaults to now.
from(bucket:"example-bucket")
|> range(start: -1h)
// Relative time range with start and stop
from(bucket:"example-bucket")
|> range(start: -1h, stop: -10m)
```
{{% note %}}
Relative ranges are relative to "now."
{{% /note %}}
###### Example absolute time range
```js
from(bucket:"example-bucket")
|> range(start: 2018-11-05T23:30:00Z, stop: 2018-11-06T00:00:00Z)
```
#### Use the following:
For this guide, use the relative time range, `-15m`, to limit query results to data from the last 15 minutes:
```js
from(bucket:"example-bucket")
|> range(start: -15m)
```
## 3. Filter your data
Pass your ranged data into the `filter()` function to narrow results based on data attributes or columns.
The `filter()` function has one parameter, `fn`, which expects an anonymous function
with logic that filters data based on columns or attributes.
Flux's anonymous function syntax is similar to Javascript's.
Records or rows are passed into the `filter()` function as a record (`r`).
The anonymous function takes the record and evaluates it to see if it matches the defined filters.
Use the `and` relational operator to chain multiple filters.
```js
// Pattern
(r) => (r.recordProperty comparisonOperator comparisonExpression)
// Example with single filter
(r) => (r._measurement == "cpu")
// Example with multiple filters
(r) => (r._measurement == "cpu") and (r._field != "usage_system" )
```
#### Use the following:
For this example, filter by the `cpu` measurement, the `usage_system` field, and the `cpu-total` tag value:
```js
from(bucket:"example-bucket")
|> range(start: -15m)
|> filter(fn: (r) =>
r._measurement == "cpu" and
r._field == "usage_system" and
r.cpu == "cpu-total"
)
```
## 4. Yield your queried data
Flux's `yield()` function outputs the filtered tables as the result of the query.
```js
from(bucket:"example-bucket")
|> range(start: -15m)
|> filter(fn: (r) =>
r._measurement == "cpu" and
r._field == "usage_system" and
r.cpu == "cpu-total"
)
|> yield()
```
Flux automatically assumes a `yield()` function at
the end of each script in order to output and visualize the data.
Explicitly calling `yield()` is only necessary when including multiple queries in the same Flux query.
Each set of returned data needs to be named using the `yield()` function.
## Congratulations!
You have now queried data from InfluxDB using Flux.
The query shown here is a barebones example.
Flux queries can be extended in many ways to form powerful scripts.
<div class="page-nav-btns">
<a class="btn prev" href="/v2.0/query-data/get-started/">Get started with Flux</a>
<a class="btn next" href="/v2.0/query-data/get-started/transform-data/">Transform your data</a>
</div>
{{< duplicate-oss >}}

View File

@ -12,225 +12,4 @@ related:
---
Flux, at its core, is a scripting language designed specifically for working with data.
This guide walks through a handful of simple expressions and how they are handled in Flux.
## Use the Flux REPL
Use the [Flux REPL](/influxdb/cloud/tools/repl/) to open the interactive Read-Eval-Print Loop (REPL).
Run the commands provided in this guide in the REPL.
##### Start the Flux REPL
```bash
./flux repl
```
## Basic Flux syntax
The code blocks below provide commands that illustrate the basic syntax of Flux.
Run these commands in the REPL.
### Simple expressions
Flux is a scripting language that supports basic expressions.
For example, simple addition:
```js
> 1 + 1
2
```
### Variables
Assign an expression to a variable using the assignment operator, `=`.
```js
> s = "this is a string"
> i = 1 // an integer
> f = 2.0 // a floating point number
```
Type the name of a variable to print its value:
```js
> s
this is a string
> i
1
> f
2
```
### Records
Flux also supports records. Each value in a record can be a different data type.
```js
> o = {name:"Jim", age: 42, "favorite color": "red"}
```
Use **dot notation** to access a properties of a record:
```js
> o.name
Jim
> o.age
42
```
Or **bracket notation**:
```js
> o["name"]
Jim
> o["age"]
42
> o["favorite color"]
red
```
{{% note %}}
Use bracket notation to reference record properties with special or
white space characters in the property key.
{{% /note %}}
### Arrays
Flux supports arrays. All values in an array must be the same type.
```js
> n = 4
> l = [1,2,3,n]
> l
[1, 2, 3, 4]
```
### Functions
Flux uses functions for most of its heavy lifting.
Below is a simple function that squares a number, `n`.
```js
> square = (n) => n * n
> square(n:3)
9
```
{{% note %}}
Flux does not support positional arguments or parameters.
Parameters must always be named when calling a function.
{{% /note %}}
### Pipe-forward operator
Flux uses the pipe-forward operator (`|>`) extensively to chain operations together.
After each function or operation, Flux returns a table or collection of tables containing data.
The pipe-forward operator pipes those tables into the next function where they are further processed or manipulated.
```js
data |> someFunction() |> anotherFunction()
```
## Real-world application of basic syntax
This likely seems familiar if you've already been through through the other
[getting started guides](/influxdb/cloud/query-data/get-started).
Flux's syntax is inspired by Javascript and other functional scripting languages.
As you begin to apply these basic principles in real-world use cases such as creating data stream variables,
custom functions, etc., the power of Flux and its ability to query and process data will become apparent.
The examples below provide both multi-line and single-line versions of each input command.
Carriage returns in Flux aren't necessary, but do help with readability.
Both single- and multi-line commands can be copied and pasted into the `influx` CLI running in Flux mode.
### Define data stream variables
A common use case for variable assignments in Flux is creating variables for one
or more input data streams.
{{< code-tabs-wrapper >}}
{{% code-tabs %}}
[Multi-line](#)
[Single-line](#)
{{% /code-tabs %}}
{{% code-tab-content %}}
```js
timeRange = -1h
cpuUsageUser =
from(bucket:"example-bucket")
|> range(start: timeRange)
|> filter(fn: (r) =>
r._measurement == "cpu" and
r._field == "usage_user" and
r.cpu == "cpu-total"
)
memUsagePercent =
from(bucket:"example-bucket")
|> range(start: timeRange)
|> filter(fn: (r) =>
r._measurement == "mem" and
r._field == "used_percent"
)
```
{{% /code-tab-content %}}
{{% code-tab-content %}}
```js
timeRange = -1h
cpuUsageUser = from(bucket:"example-bucket") |> range(start: timeRange) |> filter(fn: (r) => r._measurement == "cpu" and r._field == "usage_user" and r.cpu == "cpu-total")
memUsagePercent = from(bucket:"example-bucket") |> range(start: timeRange) |> filter(fn: (r) => r._measurement == "mem" and r._field == "used_percent")
```
{{% /code-tab-content %}}
{{< /code-tabs-wrapper>}}
These variables can be used in other functions, such as `join()`, while keeping the syntax minimal and flexible.
### Define custom functions
Create a function that returns the `N` number rows in the input stream with the highest `_value`s.
To do this, pass the input stream (`tables`) and the number of results to return (`n`) into a custom function.
Then using Flux's `sort()` and `limit()` functions to find the top `n` results in the data set.
{{< code-tabs-wrapper >}}
{{% code-tabs %}}
[Multi-line](#)
[Single-line](#)
{{% /code-tabs %}}
{{% code-tab-content %}}
```js
topN = (tables=<-, n) =>
tables
|> sort(desc: true)
|> limit(n: n)
```
{{% /code-tab-content %}}
{{% code-tab-content %}}
```js
topN = (tables=<-, n) => tables |> sort(desc: true) |> limit(n: n)
```
{{% /code-tab-content %}}
{{< /code-tabs-wrapper >}}
Using this new custom function `topN` and the `cpuUsageUser` data stream variable defined above,
we can find the top five data points and yield the results.
{{< code-tabs-wrapper >}}
{{% code-tabs %}}
[Multi-line](#)
[Single-line](#)
{{% /code-tabs %}}
{{% code-tab-content %}}
```js
cpuUsageUser
|> topN(n:5)
|> yield()
```
{{% /code-tab-content %}}
{{% code-tab-content %}}
```js
cpuUsageUser |> topN(n:5) |> yield()
```
{{% /code-tab-content %}}
{{< /code-tabs-wrapper>}}
This query will return the five data points with the highest user CPU usage over the last hour.
_More information about creating custom functions is available in the [Custom functions](/influxdb/cloud/query-data/flux/custom-functions) documentation._
<div class="page-nav-btns">
<a class="btn prev" href="/v2.0/query-data/get-started/transform-data/">Transform your data</a>
</div>
{{< duplicate-oss >}}

View File

@ -12,176 +12,4 @@ related:
- /influxdb/cloud/reference/flux/stdlib/built-in/transformations/window
---
When [querying data from InfluxDB](/influxdb/cloud/query-data/get-started/query-influxdb),
you often need to transform that data in some way.
Common examples are aggregating data into averages, downsampling data, etc.
This guide demonstrates using [Flux functions](/influxdb/cloud/reference/flux/stdlib) to transform your data.
It walks through creating a Flux script that partitions data into windows of time,
averages the `_value`s in each window, and outputs the averages as a new table.
(Remember, Flux structures all data in [tables](/influxdb/cloud/query-data/get-started/#tables).)
It's important to understand how the "shape" of your data changes through each of these operations.
## Query data
Use the query built in the previous [Query data from InfluxDB](/influxdb/cloud/query-data/get-started/query-influxdb)
guide, but update the range to pull data from the last hour:
```js
from(bucket:"example-bucket")
|> range(start: -1h)
|> filter(fn: (r) =>
r._measurement == "cpu" and
r._field == "usage_system" and
r.cpu == "cpu-total"
)
```
## Flux functions
Flux provides a number of functions that perform specific operations, transformations, and tasks.
You can also [create custom functions](/influxdb/cloud/query-data/flux/custom-functions) in your Flux queries.
_Functions are covered in detail in the [Flux functions](/influxdb/cloud/reference/flux/stdlib) documentation._
A common type of function used when transforming data queried from InfluxDB is an aggregate function.
Aggregate functions take a set of `_value`s in a table, aggregate them, and transform
them into a new value.
This example uses the [`mean()` function](/influxdb/cloud/reference/flux/stdlib/built-in/transformations/aggregates/mean)
to average values within each time window.
{{% note %}}
The following example walks through the steps required to window and aggregate data,
but there is a [`aggregateWindow()` helper function](#helper-functions) that does it for you.
It's just good to understand the steps in the process.
{{% /note %}}
## Window your data
Flux's [`window()` function](/influxdb/cloud/reference/flux/stdlib/built-in/transformations/window) partitions records based on a time value.
Use the `every` parameter to define a duration of each window.
{{% note %}}
#### Calendar months and years
`every` supports all [valid duration units](/influxdb/cloud/reference/flux/language/types/#duration-types),
including **calendar months (`1mo`)** and **years (`1y`)**.
{{% /note %}}
For this example, window data in five minute intervals (`5m`).
```js
from(bucket:"example-bucket")
|> range(start: -1h)
|> filter(fn: (r) =>
r._measurement == "cpu" and
r._field == "usage_system" and
r.cpu == "cpu-total"
)
|> window(every: 5m)
```
As data is gathered into windows of time, each window is output as its own table.
When visualized, each table is assigned a unique color.
![Windowed data tables](/img/flux/windowed-data.png)
## Aggregate windowed data
Flux aggregate functions take the `_value`s in each table and aggregate them in some way.
Use the [`mean()` function](/influxdb/cloud/reference/flux/stdlib/built-in/transformations/aggregates/mean) to average the `_value`s of each table.
```js
from(bucket:"example-bucket")
|> range(start: -1h)
|> filter(fn: (r) =>
r._measurement == "cpu" and
r._field == "usage_system" and
r.cpu == "cpu-total"
)
|> window(every: 5m)
|> mean()
```
As rows in each window are aggregated, their output table contains only a single row with the aggregate value.
Windowed tables are all still separate and, when visualized, will appear as single, unconnected points.
![Windowed aggregate data](/img/flux/windowed-aggregates.png)
## Add times to your aggregates
As values are aggregated, the resulting tables do not have a `_time` column because
the records used for the aggregation all have different timestamps.
Aggregate functions don't infer what time should be used for the aggregate value.
Therefore the `_time` column is dropped.
A `_time` column is required in the [next operation](#unwindow-aggregate-tables).
To add one, use the [`duplicate()` function](/influxdb/cloud/reference/flux/stdlib/built-in/transformations/duplicate)
to duplicate the `_stop` column as the `_time` column for each windowed table.
```js
from(bucket:"example-bucket")
|> range(start: -1h)
|> filter(fn: (r) =>
r._measurement == "cpu" and
r._field == "usage_system" and
r.cpu == "cpu-total"
)
|> window(every: 5m)
|> mean()
|> duplicate(column: "_stop", as: "_time")
```
## Unwindow aggregate tables
Use the `window()` function with the `every: inf` parameter to gather all points
into a single, infinite window.
```js
from(bucket:"example-bucket")
|> range(start: -1h)
|> filter(fn: (r) =>
r._measurement == "cpu" and
r._field == "usage_system" and
r.cpu == "cpu-total"
)
|> window(every: 5m)
|> mean()
|> duplicate(column: "_stop", as: "_time")
|> window(every: inf)
```
Once ungrouped and combined into a single table, the aggregate data points will appear connected in your visualization.
![Unwindowed aggregate data](/img/flux/windowed-aggregates-ungrouped.png)
## Helper functions
This may seem like a lot of coding just to build a query that aggregates data, however going through the
process helps to understand how data changes "shape" as it is passed through each function.
Flux provides (and allows you to create) "helper" functions that abstract many of these steps.
The same operation performed in this guide can be accomplished using the
[`aggregateWindow()` function](/influxdb/cloud/reference/flux/stdlib/built-in/transformations/aggregates/aggregatewindow).
```js
from(bucket:"example-bucket")
|> range(start: -1h)
|> filter(fn: (r) =>
r._measurement == "cpu" and
r._field == "usage_system" and
r.cpu == "cpu-total"
)
|> aggregateWindow(every: 5m, fn: mean)
```
## Congratulations!
You have now constructed a Flux query that uses Flux functions to transform your data.
There are many more ways to manipulate your data using both Flux's primitive functions
and your own custom functions, but this is a good introduction into the basic syntax and query structure.
---
_For a deeper dive into windowing and aggregating data with example data output for each transformation,
view the [Window and aggregate data](/influxdb/cloud/query-data/flux/window-aggregate) guide._
---
<div class="page-nav-btns">
<a class="btn prev" href="/v2.0/query-data/get-started/query-influxdb/">Query InfluxDB</a>
<a class="btn next" href="/v2.0/query-data/get-started/syntax-basics/">Syntax basics</a>
</div>
{{< duplicate-oss >}}

View File

@ -8,271 +8,4 @@ menu:
weight: 204
---
An _expression_ specifies the computation of a value by applying the operators and functions to operands.
## Operands and primary expressions
Operands denote the elementary values in an expression.
Primary expressions are the operands for unary and binary expressions.
A primary expressions may be a literal, an identifier denoting a variable, or a parenthesized expression.
```js
PrimaryExpression = identifier | Literal | "(" Expression ")" .
```
## Literals
Literals construct a value.
```js
Literal = int_lit
| float_lit
| string_lit
| regex_lit
| duration_lit
| date_time_lit
| pipe_receive_lit
| RecordLiteral
| ArrayLiteral
| FunctionLiteral .
```
### Record literals
Record literals construct a value with the record type.
```js
RecordLiteral = "{" RecordBody "}" .
RecordBody = WithProperties | PropertyList .
WithProperties = identifier "with" PropertyList .
PropertyList = [ Property { "," Property } ] .
Property = identifier [ ":" Expression ]
| string_lit ":" Expression .
```
**Examples**
```js
{a: 1, b: 2, c: 3}
{a, b, c}
{o with x: 5, y: 5}
{o with a, b}
```
### Array literals
Array literals construct a value with the array type.
```js
ArrayLiteral = "[" ExpressionList "]" .
ExpressionList = [ Expression { "," Expression } ] .
```
### Function literals
A _function literal_ defines a new function with a body and parameters.
The function body may be a block or a single expression.
The function body must have a return statement if it is an explicit block, otherwise the expression is the return value.
```js
FunctionLiteral = FunctionParameters "=>" FunctionBody .
FunctionParameters = "(" [ ParameterList [ "," ] ] ")" .
ParameterList = Parameter { "," Parameter } .
Parameter = identifier [ "=" Expression ] .
FunctionBody = Expression | Block .
```
##### Examples of function literals
```js
() => 1 // function returns the value 1
(a, b) => a + b // function returns the sum of a and b
(x=1, y=1) => x * y // function with default values
(a, b, c) => { // function with a block body
d = a + b
return d / c
}
```
All function literals are anonymous.
A function may be given a name using a variable assignment.
```
add = (a,b) => a + b
mul = (a,b) => a * b
```
Function literals are _closures_ and may refer to variables defined in a surrounding block.
Those variables are shared between the function literal and the surrounding block.
## Call expressions
A _call expression_ invokes a function with the provided arguments.
Arguments must be specified using the argument name.
Positional arguments are not supported.
Argument order does not matter.
When an argument has a default value, it is not required to be specified.
```js
CallExpression = "(" PropertyList ")" .
```
##### Examples of call expressions
```js
f(a:1, b:9.6)
float(v:1)
```
Use short notation in a call expression when the name of every argument matches the name of every parameter.
##### Examples of short notation in call expressions
```js
add(a: a, b: b) //long notation
add(a, b) // short notation equivalent
add = (a,b) => a + b
a = 1
b = 2
// Don't mix short and long notation.
add(a: a, b)
add(a, b: b)
```
## Pipe expressions
A _pipe expression_ is a call expression with an implicit piped argument.
Pipe expressions simplify creating long nested call chains.
Pipe expressions pass the result of the left hand expression as the _pipe argument_ to the right hand call expression.
Function literals specify which if any argument is the pipe argument using the _pipe literal_ as the argument's default value.
It is an error to use a pipe expression if the function does not declare a pipe argument.
```js
pipe_receive_lit = "<-" .
```
##### Examples of pipe expressions
```js
foo = () => // function body elided
bar = (x=<-) => // function body elided
baz = (y=<-) => // function body elided
foo() |> bar() |> baz() // equivalent to baz(x:bar(y:foo()))
```
## Index expressions
Index expressions access a value from an array based on a numeric index.
```js
IndexExpression = "[" Expression "]" .
```
## Member expressions
Member expressions access a property of a record.
They are specified using an expression in one of the following forms:
```js
rec.k
// or
rec["k"]
```
The property being accessed must be either an identifier or a string literal.
In either case the literal value is the name of the property being accessed, the identifier is not evaluated.
It is not possible to access a record's property using an arbitrary expression.
If `rec` contains an entry with property `k`, both `rec.k` and `rec["k"]` return the value associated with `k`.
If `rec` does **not** contain an entry with property `k`, both `rec.k` and `rec["k"]` return _null_.
```js
MemberExpression = DotExpression | MemberBracketExpression .
DotExpression = "." identifier .
MemberBracketExpression = "[" string_lit "]" .
```
## Conditional expressions
Conditional expressions evaluate a boolean-valued condition.
If the result is _true_, the expression that follows the `then` keyword is evaluated and returned.
If the result is _false_, the expression that follows the `else` keyword is evaluated and returned.
In either case, only the branch taken is evaluated and only side effects associated this branch will occur.
```js
ConditionalExpression = "if" Expression "then" Expression "else" Expression .
```
##### Conditional expression example
```js
color = if code == 0 then "green" else if code == 1 then "yellow" else "red"
```
{{% note %}}
According to the definition above, if a condition evaluates to a _null_ or unknown value,
the _else_ branch is evaluated.
{{% /note %}}
## Operators
Operators combine operands into expressions.
The precedence of the operators is given in the table below.
Operators with a lower number have higher precedence.
| Precedence | Operator | Description |
|:----------:|:--------: |:-------------------------- |
| 1 | `a()` | Function call |
| | `a[]` | Member or index access |
| | `.` | Member access |
| 2 | <code>\|></code> | Pipe forward |
| 3 | `^` | Exponentiation |
| 4 | `*` `/` `%` | Multiplication, division, and modulo |
| 5 | `+` `-` | Addition and subtraction |
| 6 |`==` `!=` | Comparison operators |
| | `<` `<=` | |
| | `>` `>=` | |
| |`=~` `!~` | |
| 7 | `not` | Unary logical operator |
| | `exists` | Null check operator |
| 8 | `and` | Logical AND |
| 9 | `or` | Logical OR |
| 10 | `if` `then` `else` | Conditional |
The operator precedence is encoded directly into the grammar as the following.
```js
Expression = ConditionalExpression .
ConditionalExpression = LogicalExpression
| "if" Expression "then" Expression "else" Expression .
LogicalExpression = UnaryLogicalExpression
| LogicalExpression LogicalOperator UnaryLogicalExpression .
LogicalOperator = "and" | "or" .
UnaryLogicalExpression = ComparisonExpression
| UnaryLogicalOperator UnaryLogicalExpression .
UnaryLogicalOperator = "not" | "exists" .
ComparisonExpression = AdditiveExpression
| ComparisonExpression ComparisonOperator AdditiveExpression .
ComparisonOperator = "==" | "!=" | "<" | "<=" | ">" | ">=" | "=~" | "!~" .
AdditiveExpression = MultiplicativeExpression
| AdditiveExpression AdditiveOperator MultiplicativeExpression .
AdditiveOperator = "+" | "-" .
MultiplicativeExpression = PipeExpression
| MultiplicativeExpression MultiplicativeOperator PipeExpression .
MultiplicativeOperator = "*" | "/" | "%" | "^" .
PipeExpression = PostfixExpression
| PipeExpression PipeOperator UnaryExpression .
PipeOperator = "|>" .
UnaryExpression = PostfixExpression
| PrefixOperator UnaryExpression .
PrefixOperator = "+" | "-" .
PostfixExpression = PrimaryExpression
| PostfixExpression PostfixOperator .
PostfixOperator = MemberExpression
| CallExpression
| IndexExpression .
```
{{% warn %}}
Dividing by 0 or using the mod operator with a divisor of 0 will result in an error.
{{% /warn %}}
_Also see [Flux Operators](/influxdb/cloud/reference/flux/language/operators)._
{{< duplicate-oss >}}

View File

@ -8,272 +8,4 @@ menu:
weight: 213
---
{{% note %}}
This document is a living document and may not represent the current implementation of Flux.
Any section that is not currently implemented is commented with a **[IMPL#XXX]** where
**XXX** is an issue number tracking discussion and progress towards implementation.
{{% /note %}}
A **type** defines the set of values and operations on those values.
Types are never explicitly declared as part of the syntax except as part of a [builtin statement](/influxdb/cloud/reference/flux/language/system-built-ins/).
Types are always inferred from the usage of the value.
Type inference follows a Hindley-Milner style inference system.
## Union types
A union type defines a set of types.
In the examples below, a union type is specified as follows:
```js
T = t1 | t2 | ... | tn
```
where `t1`, `t2`, ..., and `tn` are types.
In the example above a value of type `T` is either of type `t1`, type `t2`, ..., or type `tn`.
## Basic types
All Flux data types are constructed from the following types:
### Null types
The **null type** represents a missing or unknown value.
The **null type** name is `null`.
There is only one value that comprises the _null type_ and that is the _null_ value.
A type `t` is nullable if it can be expressed as follows:
```js
t = {s} | null
```
where `{s}` defines a set of values.
### Boolean types
A _boolean type_ represents a truth value, corresponding to the preassigned variables `true` and `false`.
The boolean type name is `bool`.
The boolean type is nullable and can be formally specified as follows:
```js
bool = {true, false} | null
```
### Numeric types
A _numeric type_ represents sets of integer or floating-point values.
The following numeric types exist:
```
uint the set of all unsigned 64-bit integers | null
int the set of all signed 64-bit integers | null
float the set of all IEEE-754 64-bit floating-point numbers | null
```
{{% note %}}
All numeric types are nullable.
{{% /note %}}
### Time types
A _time type_ represents a single point in time with nanosecond precision.
The time type name is `time`.
The time type is nullable.
#### Timestamp format
Flux supports [RFC3339 timestamps](/influxdb/cloud/reference/glossary/#rfc3339-timestamp):
- `YYYY-MM-DD`
- `YYYY-MM-DDT00:00:00Z`
- `YYYY-MM-DDT00:00:00.000Z`
### Duration types
A _duration type_ represents a length of time with nanosecond precision.
The duration type name is `duration`.
The duration type is nullable
Durations can be added to times to produce a new time.
##### Examples of duration types
```js
1ns // 1 nanosecond
1us // 1 microsecond
1ms // 1 millisecond
1s // 1 second
1m // 1 minute
1h // 1 hour
1d // 1 day
1w // 1 week
1mo // 1 calendar month
1y // 1 calendar year
3d12h4m25s // 3 days, 12 hours, 4 minutes, and 25 seconds
```
### String types
A _string type_ represents a possibly empty sequence of characters.
Strings are immutable and cannot be modified once created.
The string type name is `string`.
The string type is nullable.
{{% note %}}
An empty string is **not** a _null_ value.
{{% /note %}}
The length of a string is its size in bytes, not the number of characters,
since a single character may be multiple bytes.
### Bytes types
A _bytes type_ represents a sequence of byte values.
The bytes type name is `bytes`.
## Regular expression types
A _regular expression type_ represents the set of all patterns for regular expressions.
The regular expression type name is `regexp`.
The regular expression type is **not** nullable.
## Composite types
These are types constructed from basic types.
Composite types are not nullable.
### Array types
An _array type_ represents a sequence of values of any other type.
All values in the array must be of the same type.
The length of an array is the number of elements in the array.
### Record types
A _record type_ represents a set of unordered key and value pairs.
The key must always be a string.
The value may be any other type, and need not be the same as other values within the record.
Keys in a record may only be referenced statically.
Type inference determines the properties that are present in a record.
If type inference determines all the properties in a record, it is said to be "bounded."
Not all keys may be known in the type of a record, in which case the record is said to be "unbounded."
An unbounded record may contain any property in addition to the properties it is known to contain.
### Function types
A _function type_ represents a set of all functions with the same argument and result types.
{{% note %}}
[IMPL#249](https://github.com/influxdata/platform/issues/249) Specify type inference rules.
{{% /note %}}
### Generator types
A _generator type_ represents a value that produces an unknown number of other values.
The generated values may be of any other type, but must all be the same type.
{{% note %}}
[IMPL#658](https://github.com/influxdata/platform/query/issues/658) Implement Generators types.
{{% /note %}}
## Polymorphism
Flux functions can be polymorphic, meaning a function can be applied to arguments of different types.
Flux supports parametric, record, and ad hoc polymorphism.
### Parametric polymorphism
Parametric polymorphism is the notion that a function can be applied uniformly to arguments of any type.
For example:
```js
f = (x) => x
f(x: 1)
f(x: 1.1)
f(x: "1")
f(x: true)
f(x: f)
```
The identifiers, `a` and `b`, in the body of the `add` function are used as both `int` and `float` types.
### Record polymorphism
Record polymorphism is the notion that a function can be applied to different types of records.
For example:
```js
john = {name:"John", lastName:"Smith"}
jane = {name:"Jane", age:44}
// John and Jane are records with different types.
// We can still define a function that can operate on both records safely.
// name returns the name of a person
name = (person) => person.name
name(person:john) // John
name(person:jane) // Jane
device = {id: 125325, lat: 15.6163, lon: 62.6623}
name(person:device) // Type error, "device" does not have a property name.
```
Records of differing types can be passed to the same function as long as they contain the necessary properties.
The necessary properties are determined by the use of the record.
### Ad hoc polymorphism
Ad hoc polymorphism is the notion that a function can be applied to arguments of
different types with different behavior depending on the type.
```js
add = (a, b) => a + b
// Integer addition
add(a: 1, b: 1)
// String concatenation
add(a: "str", b: "ing")
// Addition not defined for boolean data types
add(a: true, b: false)
```
## Type constraints
Type constraints are to implement static ad hoc polymorphism.
For example, the following function is defined only for `Addable` types:
```js
add = (a, b) => a + b
```
Passing a record to `add()` results in compile-time type error because records are not addable.
```js
// Records are not Addable and will result in an error.
add(a: {}, b: {})
```
Constraints are never explicitly declared but rather inferred from the context.
### Addable constraint
Addable types are those the binary arithmetic operator `+` accepts.
Integer, Uinteger, Float, and String types are `Addable`.
### Subtractable constraint
Subtractable types are those the binary arithmetic operator `-` accepts.
Integer, Uinteger, and Float types are `Subtractable`.
### Divisible constraint
Divisible types are those the binary arithmetic operator `\` accepts.
Integer, Uinteger, and Float types are `Divisible`.
### Numeric Constraint
Integer, Uinteger, and Float types are `Numeric`.
### Comparable Constraint
Comparable types are those the binary comparison operators `<`, `<=`, `>`, or `>=` accept.
Integer, Uinteger, Float, String, Duration, and Time types are `Comparable`.
### Equatable Constraint
Equatable types are those that can be compared for equality using the `==` or `!=` operators.
Boolean, Integer, Uinteger, Float, String, Duration, Time, Bytes, Array, and Record types are `Equatable`.
### Nullable Constraint
Nullable types are those that can be _null_.
Boolean, Integer, Uinteger, Float, String, Duration, and Time types are `Nullable`.
### Record Constraint
Records are the only types that fall under this constraint.
### Negatable Constraint
Negatable types ore those the unary arithmetic operator `-` accepts.
Integer, Uinteger, Float, and Duration types are `Negatable`.
### Timeable Constraint
Duration and Time types are `Timeable`.
{{< duplicate-oss >}}

View File

@ -0,0 +1,15 @@
---
title: Flux Dictionary package
list_title: Dictionary package
description: >
The Flux dictionary package provides functions for interacting with dictionary types.
Import the `dict` package.
menu:
influxdb_cloud_ref:
name: Dictionary
parent: Flux standard library
weight: 202
influxdb/v2.0/tags: [package, functions]
---
{{< duplicate-oss >}}

View File

@ -0,0 +1,13 @@
---
title: dict.fromList() function
description: >
The `dict.fromList()` function creates a dictionary from a list of records with
`key` and `value` properties.
menu:
influxdb_cloud_ref:
name: dict.fromList
parent: Dictionary
weight: 301
---
{{< duplicate-oss >}}

View File

@ -0,0 +1,13 @@
---
title: dict.get() function
description: >
The `dict.get()` function returns the value of a specified key in a dictionary
or a default value if the key does not exist.
menu:
influxdb_cloud_ref:
name: dict.get
parent: Dictionary
weight: 301
---
{{< duplicate-oss >}}

View File

@ -0,0 +1,14 @@
---
title: dict.insert() function
description: >
The `dict.insert()` function inserts a key value pair into a dictionary and
returns a new, updated dictionary.
If the key already exists in the dictionary, the function overwrites the existing value.
menu:
influxdb_cloud_ref:
name: dict.insert
parent: Dictionary
weight: 301
---
{{< duplicate-oss >}}

View File

@ -0,0 +1,13 @@
---
title: dict.remove() function
description: >
The `dict.remove()` function removes a key value pair from a dictionary and returns
and updated dictionary.
menu:
influxdb_cloud_ref:
name: dict.remove
parent: Dictionary
weight: 301
---
{{< duplicate-oss >}}

View File

@ -66,12 +66,22 @@ The message is stored in the `_message` column.
_**Data type:** Function_
### data
Meta data used to identify this check.
**InfluxDB populates check data.**
Metadata used to identify this check and append tags to each row.
_**Data type:** Record_
The data record should contain the following fields:
- **_check_id**: check ID
- **_check_name**: check name
- **_type**: check type (threshold, deadman, or custom)
- **tags**: tags to append to each checked record (for example: `{foo: "bar", baz: "quz"}`)
The InfluxDB monitoring and alerting system uses `monitor.check()` to store information
about checks and automatically assigns the `_check_id` and `_check_name` values.
If writing a custom check task, we recommend using **unique arbitrary** values
for `_check_id` and `_check_name`.
## Examples
### Monitor disk usage

View File

@ -132,6 +132,6 @@ Flux queries can be extended in many ways to form powerful scripts.
<div class="page-nav-btns">
<a class="btn prev" href="/v2.0/query-data/get-started/">Get started with Flux</a>
<a class="btn next" href="/v2.0/query-data/get-started/transform-data/">Transform your data</a>
<a class="btn prev" href="/influxdb/v2.0/query-data/get-started/">Get started with Flux</a>
<a class="btn next" href="/influxdb/v2.0/query-data/get-started/transform-data/">Transform your data</a>
</div>

View File

@ -58,7 +58,9 @@ this is a string
```
### Records
Flux also supports records. Each value in a record can be a different data type.
Flux also supports records, collections of key-value pairs.
Each key must be a string.
Values can be a different data types.
```js
> o = {name:"Jim", age: 42, "favorite color": "red"}
@ -99,6 +101,32 @@ Flux supports arrays. All values in an array must be the same type.
[1, 2, 3, 4]
```
Use **bracket notation** to access a value at a specific index in an array:
```js
> a = ["foo","bar","baz","quz"]
> a[0]
foo
```
### Dictionaries
Flux supports dictionaries, collections of key value pairs where keys can be any type,
but all keys must be the same type.
All values in a dictionary must be the same type.
```js
> d = [1: "foo", 2: "bar"]
```
Use the [`dict.get()` function](/influxdb/v2.0/reference/flux/stdlib/dict/get/)
to access properties in a dictionary:
```js
> import "dict"
> dict.get(dict: d, key: "1", default: "")
foo
```
### Functions
Flux uses functions for most of its heavy lifting.
Below is a simple function that squares a number, `n`.
@ -232,5 +260,5 @@ This query will return the five data points with the highest user CPU usage over
_More information about creating custom functions is available in the [Custom functions](/influxdb/v2.0/query-data/flux/custom-functions) documentation._
<div class="page-nav-btns">
<a class="btn prev" href="/v2.0/query-data/get-started/transform-data/">Transform your data</a>
<a class="btn prev" href="/influxdb/v2.0/query-data/get-started/transform-data/">Transform your data</a>
</div>

View File

@ -182,6 +182,6 @@ view the [Window and aggregate data](/influxdb/v2.0/query-data/flux/window-aggre
---
<div class="page-nav-btns">
<a class="btn prev" href="/v2.0/query-data/get-started/query-influxdb/">Query InfluxDB</a>
<a class="btn next" href="/v2.0/query-data/get-started/syntax-basics/">Syntax basics</a>
<a class="btn prev" href="/influxdb/v2.0/query-data/get-started/query-influxdb/">Query InfluxDB</a>
<a class="btn next" href="/influxdb/v2.0/query-data/get-started/syntax-basics/">Syntax basics</a>
</div>

View File

@ -35,6 +35,7 @@ Literal = int_lit
| pipe_receive_lit
| RecordLiteral
| ArrayLiteral
| DictLiteral
| FunctionLiteral .
```
@ -68,6 +69,28 @@ ArrayLiteral = "[" ExpressionList "]" .
ExpressionList = [ Expression { "," Expression } ] .
```
### Dictionary literals
Dictionary literals construct a value with the dict type.
```js
DictLiteral = EmptyDict | "[" AssociativeList "]" .
EmptyDict = "[" ":" "]" .
AssociativeList = Association { "," AssociativeList } .
Association = Expression ":" Expression .
```
Keys can be arbitrary expressions.
The type system enforces that all keys are of the same type.
**Examples**
```js
a = "a"
b = [:] // empty dictionary
c = [a: 1, "b": 2] // dictionary mapping string values to integers
d = [a: 1, 2: 3] // type error: cannot mix string and integer keys
```
### Function literals
A _function literal_ defines a new function with a body and parameters.

View File

@ -148,19 +148,20 @@ If type inference determines all the properties in a record, it is said to be "b
Not all keys may be known in the type of a record, in which case the record is said to be "unbounded."
An unbounded record may contain any property in addition to the properties it is known to contain.
### Dictionary types
A _dictionary type_ is a collection that associates keys to values.
Keys must be comparable and of the same type.
Values must also be of the same type.
### Function types
A _function type_ represents a set of all functions with the same argument and result types.
{{% note %}}
[IMPL#249](https://github.com/influxdata/platform/issues/249) Specify type inference rules.
{{% /note %}}
### Generator types
A _generator type_ represents a value that produces an unknown number of other values.
The generated values may be of any other type, but must all be the same type.
{{% note %}}
[IMPL#658](https://github.com/influxdata/platform/query/issues/658) Implement Generators types.
[IMPL#412](https://github.com/influxdata/flux/issues/412) Implement Generators types.
{{% /note %}}
## Polymorphism

View File

@ -0,0 +1,22 @@
---
title: Flux Dictionary package
list_title: Dictionary package
description: >
The Flux dictionary package provides functions for interacting with dictionary types.
Import the `dict` package.
menu:
influxdb_2_0_ref:
name: Dictionary
parent: Flux standard library
weight: 202
influxdb/v2.0/tags: [package, functions]
---
The Flux dictionary package provides functions for interacting with [dictionary types](/influxdb/v2.0/reference/flux/language/types/#dictionary-types).
Import the `dict` package.
```js
import "dict"
```
{{< children type="functions" show="pages" >}}

View File

@ -0,0 +1,52 @@
---
title: dict.fromList() function
description: >
The `dict.fromList()` function creates a dictionary from a list of records with
`key` and `value` properties.
menu:
influxdb_2_0_ref:
name: dict.fromList
parent: Dictionary
weight: 301
---
The `dict.fromList()` function creates a dictionary from a list of records with
`key` and `value` properties.
```js
import "dict"
dict.fromList(
pairs: [
{key: 1, value: "foo"},
{key: 2, value: "bar"}
]
)
```
## Parameters
### pairs
({{< req >}}) List of records, each containing `key` and `value` properties.
_**Data type:** Array of records_
## Examples
##### Create a dictionary from a list of records
```js
import "dict"
// Define a new dictionary using an array of records
d = dict.fromList(
pairs: [
{key: 1, value: "foo"},
{key: 2, value: "bar"}
]
)
// Return a property of the dictionary
dict.get(dict: d, key: 1, default: "")
// Returns foo
```

View File

@ -0,0 +1,63 @@
---
title: dict.get() function
description: >
The `dict.get()` function returns the value of a specified key in a dictionary
or a default value if the key does not exist.
menu:
influxdb_2_0_ref:
name: dict.get
parent: Dictionary
weight: 301
---
The `dict.get()` function returns the value of a specified key in a dictionary
or a default value if the key does not exist.
```js
import "dict"
dict.get(
dict: [1: "foo", 2: "bar"],
key: 1,
default: ""
)
```
## Parameters
<p>
{{< req "All paremeters are required" >}}
</p>
### dict
Dictionary to return a value from.
_**Data type:** Dictionary_
### key
Key to return from the dictionary.
_**Data type:** String | Boolean | Integer | Uinteger | Float | Time | Bytes_
### default
Default value to return if the `key` does not exist in the dictionary.
Must be the same type as values in the dictionary.
_**Data type:** String | Boolean | Integer | Uinteger | Float | Time | Bytes_
## Examples
##### Return a property of a dictionary
```js
import "dict"
d = [1: "foo", 2: "bar"]
dict.get(
dict: d,
key: 1,
default: ""
)
// Returns foo
```

View File

@ -0,0 +1,87 @@
---
title: dict.insert() function
description: >
The `dict.insert()` function inserts a key value pair into a dictionary and
returns a new, updated dictionary.
If the key already exists in the dictionary, the function overwrites the existing value.
menu:
influxdb_2_0_ref:
name: dict.insert
parent: Dictionary
weight: 301
---
The `dict.insert()` function inserts a key value pair into a dictionary and returns
a new, updated dictionary.
If the key already exists in the dictionary, the function overwrites the existing value.
```js
import "dict"
dict.insert(
dict: [1: "foo", 2: "bar"],
key: 3,
value: "baz"
)
```
## Parameters
<p>
{{< req "All paremeters are required" >}}
</p>
### dict
Dictionary to update.
_**Data type:** Dictionary_
### key
Key to insert into the dictionary.
Must be the same type as existing keys in the dictionary.
_**Data type:** String | Boolean | Integer | Uinteger | Float | Time | Bytes_
### default
Value to insert into the dictionary.
Must be the same type as existing values in the dictionary.
_**Data type:** String | Boolean | Integer | Uinteger | Float | Time | Bytes_
## Examples
##### Insert a new key-value pair into a dictionary
```js
import "dict"
d = [1: "foo", 2: "bar"]
dNew = dict.insert(
dict: d,
key: 3,
value: "baz"
)
// Verify the new key-value pair was inserted
dict.get(dict: dNew, key: 3, default: "")
// Returns baz
```
##### Overwrite an existing key-value pair in a dictionary
```js
import "dict"
d = [1: "foo", 2: "bar"]
dNew = dict.insert(
dict: d,
key: 2,
value: "baz"
)
// Verify the new key-value pair was overwritten
dict.get(dict: dNew, key: 2, default: "")
// Returns baz
```

View File

@ -0,0 +1,62 @@
---
title: dict.remove() function
description: >
The `dict.remove()` function removes a key value pair from a dictionary and returns
an updated dictionary.
menu:
influxdb_2_0_ref:
name: dict.remove
parent: Dictionary
weight: 301
---
The `dict.remove()` function removes a key value pair from a dictionary and returns
an updated dictionary.
```js
import "dict"
dict.remove(
dict: [1: "foo", 2: "bar"],
key: 1
)
```
## Parameters
<p>
{{< req "All paremeters are required" >}}
</p>
### dict
Dictionary to remove a key-value pair from.
_**Data type:** Dictionary_
### key
Key to remove from the dictionary.
Must be the same type as existing keys in the dictionary.
_**Data type:** String | Boolean | Integer | Uinteger | Float | Time | Bytes_
## Examples
##### Remove a property from a dictionary
```js
import "dict"
d = [1: "foo", 2: "bar"]
dNew = dict.remove(
dict: d,
key: 1
)
// Verify the key-value pairs was removed
dict.get(dict: dNew, key: 1, default: "")
// Returns an empty string
dict.get(dict: dNew, key: 2, default: "")
// Returns bar
```

View File

@ -8,6 +8,23 @@ menu:
name: Flux
---
## v0.99.0 [2020-12-14]
### Features
- Evaluate [dictionary literals](/influxdb/v2.0/reference/flux/language/expressions/#dictionary-literals).
- Infer the type of dictionary literals.
- Parse and format dictionary literals.
- Add a pure Flux test runner.
### Bug fixes
- Ensure `csv.from()` only returns one result.
- Change `extern` parsing code to return a more descriptive error message.
- Do not allow containers within a record to be null.
- Retrieve `now` option before running a Flux script.
- Fix misspellings in the [Flux README](https://github.com/influxdata/flux/blob/master/README.md).
---
## v0.98.0 [2020-12-07]
### Features