Splunk® Cloud Services

SPL2 Search Reference

Acrobat logo Download manual as PDF


Acrobat logo Download topic as PDF

Multivalue and array functions

For an overview about the stats and charting functions, see Overview of SPL2 stats and chart functions.

dataset()

The dataset function aggregates events into arrays of SPL2 field-value objects. See object in Built-in data types.

Usage

You can use this function in the SELECT clause in the from command and with the stats command.

There are three supported syntaxes for the dataset() function:

Syntax Data returned
dataset() The function syntax returns all of the fields in the events that match your search criteria. Use with or without a BY clause.
dataset<field-list> The function syntax returns only the specified fields in each event that match your search criteria. The list of fields must be a comma-separated list. Use with or without a BY clause.
dataset_nogroupby( [field-list] ) Use only with a BY clause, such as the GROUPBY clause in the from command or the BY clause with the stats command.


This function syntax removes the group by field from the arrays that are generated. You can return all of the fields in the events or only the specified fields that match your search criteria. When used with the GROUPBY clause, include the group by field in the SELECT clause.

Different output based on the BY clause used

When you specify a BY clause field, the results are organized by that field. The values in the group by field are included in the array.

However, the output you see depends on whether you use the GROUPBY clause with the from command or the BY clause with the stats command:

  • The GROUPBY clause in the from command returns only one field that contains the arrays, unless you specifically add the group by field to the SELECT clause.
  • The BY clause in the stats command returns two fields. One field contains the values from the BY clause field and another field contains the arrays.

For an illustration of this behavior, see the examples below that include a BY clause.

Examples

1. Return all fields and values in a single array

You can create a dataset array from all of the fields and values in the search results.

Consider this set of data:

_time department username
13 Apr 2023 13:02:45.000 PM Engineering Claudia Garcia
13 Apr 2023 10:52:41.000 AM IT Vanya Patel
13 Apr 2023 06:23:48.000 AM Personnel Alex Martin

Use the dataset function to create an array from all of the fields and values using the following search:

...| stats dataset()

The results look something like this:

dataset
[{_time: 13 Apr 2023 13:02:45.000 PM, department: Engineering, username: "Claudia Garcia"}, {_time: 13 Apr 2023 10:52:41.000 AM, department: IT, username: "Vanya Patel"}, {_time: 13 Apr 2023 06:23:48.000 AM, department: Personnel, username: "Alex Martin"}]

If you don't specify any fields with the dataset function, all of the fields are included in a single dataset array. A single dataset array is also returned if you specify a wildcard with the dataset function, for example: dataset(*).

2. Return specific fields in an array

You can specify multiple fields to populate the dataset arrays.

Consider this set of data:

_time host action department uid username
13 Apr 2023 13:02:45.000 PM mailsv2 Failed password Engineering 1066 Claudia Garcia
13 Apr 2023 10:52:41.000 AM mailsv1 Failed password IT 1815 Vanya Patel
13 Apr 2023 06:23:48.000 AM mailsv3 Session closed Personnel 1916 Alex Martin
13 Apr 2023 06:23:48.000 AM mailsv3 Failed password Engineering 1862 Wei Zhang
12 Apr 2023 20:18:36.000 PM mailsv1 Session closed Engineering 1690 Rutherford Sullivan

The following search creates a dataset array with only the values from the department and username fields.

| FROM main SELECT dataset(department, username)

The results look something like this:

dataset(department, username)
[{department: Engineering, username: "Claudia Garcia"}, {department: IT, username: "Vanya Patel"}, {department: Personnel, username: "Alex Martin"}, {department: Engineering, username: "Wei Zhang"},{department: Engineering, username: "Rutherford Sullivan"}]

3. Use a BY clause to create separate arrays

You can use a BY clause to organize the search results into separate dataset arrays.

Consider this set of data, which is the same set of data in the previous example:

_time host action department uid username
13 Apr 2023 13:02:45.000 PM mailsv2 Failed password Engineering 1066 Claudia Garcia
13 Apr 2023 10:52:41.000 AM mailsv1 Failed password IT 1815 Vanya Patel
13 Apr 2023 06:23:48.000 AM mailsv3 Session closed Personnel 1916 Alex Martin
13 Apr 2023 06:23:48.000 AM mailsv3 Failed password Engineering 1862 Wei Zhang
12 Apr 2023 20:18:36.000 PM mailsv1 Session closed Engineering 1690 Rutherford Sullivan

The following search organizes the dataset arrays by department. Each dataset array contains the user ID and username. The AS keyword is used to rename the output field employees. Otherwise the output field would be named dataset(uid, username).

| FROM main GROUP BY department SELECT dataset(uid, username) AS employees

Because this search uses the from command, the GROUP BY clause is used before the SELECT clause. If you use this function with the stats command, you would specify the BY clause.

The results look something like this:

employees
[{uid: 1066, username: "Claudia Garcia"}, {uid: 1690, username: "Rutherford Sullivan"}, {uid: 1862, username: "Wei Zhang"}]
[{uid: 1815 , username: "Vanya Patel"}]
[{uid: 1916, username: "Alex Martin"}]

Notice that the GROUP BY field is not returned in the output. To return the GROUP BY field, you must include that field in the SELECT clause.

4. BY clause output differences

The previous example shows the output using the from command GROUPBY clause when you specify a set of field names with the dataset function.

The following search uses the from command GROUPBY clause and returns all of the fields:

| FROM main GROUP BY department SELECT dataset() AS employees

The results look like this:

employees
[{host: mailsv2, action: Failed password, department: Engineering, uid: 1066, username: "Claudia Garcia"}, {host: mailsv1, action: Session closed, department: Engineering, uid: 1690, username: "Rutherford Sullivan"}, {host: mailsv3, action: Failed password, department: Engineering, uid: 1862, username: "Wei Zhang"}]
[{host: mailsv1, action: Failed password, department: IT, uid: 1815 , username: "Vanya Patel"}]
[{host: mailsv3, action: Session closed, department: Personnel, uid: 1916, username: "Alex Martin"}]

Here is a similar search using the stats command:

| FROM main | stats dataset() BY department AS employees

The results look like this:

department employees
Engineering [{host: mailsv2, action: Failed password, department: Engineering, uid: 1066, username: "Claudia Garcia"}, {host: mailsv1, action: Session closed, department: Engineering, uid: 1690, username: "Rutherford Sullivan"}, {host: mailsv3, action: Failed password, department: Engineering, uid: 1862, username: "Wei Zhang"}]
IT [{host: mailsv1, action: Failed password, department: IT, uid: 1815 , username: "Vanya Patel"}]
Personnel [{host: mailsv3, action: Session closed, department: Personnel, uid: 1916, username: "Alex Martin"}]

The stats command returns two fields, the BY clause field department and the employees field.

Notice that the group by field, department, is included in the arrays with both the GROUP BY clause in the from command and the BY clause in the stats command. You can remove the group by field from the arrays by using the dataset_nogrouby() syntax, described in the next example.

5. Using the dataset_nogroupby() syntax

The previous example shows the output using a BY clause in the search, with both the from and the stats commands. The group by field appears in the arrays. To remove the group by field from the arrays, use the dataset_nogroupby() syntax.

The following search uses the from command with the dataset_nogroupby() syntax:

| FROM main GROUP BY department SELECT dataset_nogroupby() AS employees

The results look like this:

employees
[{host: mailsv2, action: Failed password, uid: 1066, username: "Claudia Garcia"}, {host: mailsv1, action: Session closed, uid: 1690, username: "Rutherford Sullivan"}, {host: mailsv3, action: Failed password, uid: 1862, username: "Wei Zhang"}]
[{host: mailsv1, action: Failed password, uid: 1815 , username: "Vanya Patel"}]
[{host: mailsv3, action: Session closed, uid: 1916, username: "Alex Martin"}]

The search returns a set of arrays, but there is no way to determine what the group arrays belong to.

However, when you include the group by field in the SELECT clause or use the stats command with dataset_nogroupby() syntax the group by information is returned n a separate field.

For example, the following two searches return the same results:

| FROM main GROUP BY department SELECT department, dataset_nogroupby() AS employees

| FROM main | stats dataset_nogroupby() BY department AS employees

The results look like this:

department employees
Engineering [{host: mailsv2, action: Failed password, uid: 1066, username: "Claudia Garcia"}, {host: mailsv1, action: Session closed, uid: 1690, username: "Rutherford Sullivan"}, {host: mailsv3, action: Failed password, uid: 1862, username: "Wei Zhang"}]
IT [{host: mailsv1, action: Failed password, uid: 1815 , username: "Vanya Patel"}]
Personnel [{host: mailsv3, action: Session closed, uid: 1916, username: "Alex Martin"}]

list(<value>)

The list function returns a multivalue entry from the values in a field. The order of the values reflects the order of the events.

Usage

You can use this function with the stats, streamstats, and timechart commands.

  • If more than 100 values are in the field, only the first 100 are returned.
  • This function processes field values as strings.

Example

To illustrate what the list function does, let's start by generating a few simple results.

  1. Use the from and streamstats commands to generate a set of 11 results that are simply timestamps and a count of the results, which are used as row numbers. Empty arrays with the from command generate the timestamps.

    | from [{},{},{},{},{},{},{},{},{},{},{}] | streamstats count AS rowNumber

    There are 11 results. Th first few results look something like this:

    _time rowNumber
    2019-10-10T07:19:02.000-07:00 1
    2019-10-10T07:19:02.000-07:00 2
    2019-10-10T07:19:02.000-07:00 3
    2019-10-10T07:19:02.000-07:00 4
    2019-10-10T07:19:02.000-07:00 5

    Notice that each result appears on a separate row, with a line between each row.


  2. Add the stats command with the list function to the search. The numbers are returned in ascending order in a single, multivalue result.

    | from [{},{},{},{},{},{},{},{},{},{},{}] | streamstats count AS rowNumber | stats list(rowNumber) AS numbers

    The results look something like this:

    numbers
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    Notice that this is a single result with multiple values. There are no lines between each value.

  3. Compare this result with the results returned by the values function.

pivot(<key>,<value>)

The pivot function aggregates the values in a field and returns the results as an object. See object in the list of built-in data types.

Usage

The <key> argument can be a single field or a string template, which can reference multiple fields.

The <value> argument must be an aggregate, such as count() or sum().

You can use this function with the SELECT clause in the from command, or with the stats command.

Examples

Using the pivot function

Consider the following data that's in the main dataset:
status host
200 www1
200 www2
200 www1
400 www2
400 www1
400 www3
403 www2
404 www2
Use the pivot function to create an object that summarizes the HTTP status values for each separate host. The search looks like this:

FROM main GROUP BY host SELECT host, pivot(status, count())

The results look something like this:
host pivot(status,count())
www1 {"200":2,"400":1}
www2 {"200":1,"400":1,"403":1,"404":1}
www3 {"400":1}


You can use the pivot function with the stats command to accomplish the same results:

FROM main | stats pivot(status,count()) as pivotStatus by host

In this search the output field, pivot(status,count()), is renamed using the AS clause.
This search returns the same results as the previous search and looks something like this:
host pivotStatus
www1 {"200":2,"400":1}
www2 {"200":1,"400":1,"403":1,"404":1}
www3 {"400":1}

Creating nested objects with the pivot function

You can use nested pivot functions to create nested objects.
Consider the following data:
status host action
200 www1 purchase
200 www2 purchase
200 www1 addtocart
200 www2 purchase
400 www1 addtocart
400 www1 purchase
403 www2 changequantity
404 www1 view
404 www3 purchase
404 www2 changequantity
404 www1 purchase
You can use one pivot function as the <value> argument in another pivot function to create nested objects:

FROM main GROUP BY status SELECT status, pivot(host, pivot(action, count())) AS nestedPivot

The results look something like this:
status nestedPivot
200 {"www1":{"addtocart":1,"purchase":1},"www2":{"purchase":2}}
400 {"www1":{"addtocart":1,"purchase":1}}
403 {"www2":{"changequantity":1}}
404 {"www1":{"purchase":1,"view":1},"www2":{"changequantity":1},"www3":{"purchase":1}}

Using a string template with the pivot function

You can use a string template in the <value> argument of the pivot function.
In this example, the string template contains two template expressions, ${name} and ${city}, which are field names. The entire string template is enclosed in double quotation marks:

SELECT pivot("${name} in ${city}", count()) AS mylist FROM main

Suppose these are the values in the name and city fields:
name city date
Claudia London 2020-04-13
Alex Berlin 2020-04-19
Wei Sydney 2020-04-21
Claudia London 2020-04-30
The results look something like this:
mylist
{"Alex in Berlin":1,"Claudia in London":2,"Wei in Sydney":1}
You can add the flatten command to the search:

SELECT pivot("${name} in ${city}", count()) AS mylist FROM main | flatten mylist

The results look something like this:
Alex in Berlin Claudia in London Wei in Sydney mylist
1 2 1 {"Alex in Berlin":1,"Claudia in London":2,"Wei in Sydney":1}

unpivot(<key>,<value>)

The unpivot function transposes search results into an array of one or more objects.

Usage

Use the <key> and <value> parameters to label the values in the objects. These parameters must be strings.

You can use this function in the SELECT clause in the from command and with the stats command.

Examples

1. Unpivot columnar search results

The following search results show the sum of the values in the bytes field for each host:

host SumOfBytes
www1 92726
www2 113377
www3 115699
www4 105869

The following search uses the unpivot function to transpose the results into an array:

... | stats unpivot("field", "value") by host

The results look like this:

host unpivot("field", "value")
www1 [{"field":"SumOfBytes","value":92726}]
www2 [{"field":"SumOfBytes","value":113377}]
www3 [{"field":"SumOfBytes","value":115699}]
www4 [{"field":"SumOfBytes","value":105869}]

If you don't specify a BY clause, the results look like this:

unpivot("field", "value")
[{"field":"SumOfBytes","value":92726},{"field":"host","value":"www1"},{"field":"SumOfBytes","value":113377},{"field":"host","value":"www2"},{"field":"SumOfBytes","value":115699},{"field":"host","value":"www3"},{"field":"SumOfBytes","value":105869},{"field":"host","value":"www4"}]

2. Unpivot arrays

The following search results, in the $pivot view, contain a set of arrays with a count of the HTTP status codes organized by action:

action CountByActions
addtocart {"200":28,"400":3,"408":1,"505":2}
changequantity {"200":4}
purchase {"200":37,"404":1,"503":1,"505":1}
remove {"200":8}
view {"200":21,"400":1,"408":1,"505":2}

The following search uses the unpivot function to transpose the $pivot view results:

FROM $pivot GROUPBY action SELECT action, unpivot("Stats", "Values") AS AggregationSummary

The results look like this:

action AggregationSummary
addtocart [{"Stats":"CountByActions","Values":{"200":28,"400":3,"408":1,"505":2}}]
changequantity [{"Stats":"CountByActions","Values":{"200":4}}]
purchase [{"Stats":"CountByActions","Values":{"200":37,"404":1,"503":1,"505":1}}]
remove [{"Stats":"CountByActions","Values":{"200":8}}]
view [{"Stats":"CountByActions","Values":{"200":21,"400":1,"408":1,"505":2}}]

values(<value>)

The values function returns a list of the distinct values in a field as a multivalue entry.

Usage

You can use this function with the stats, streamstats, and timechart commands.

  • By default there is no limit to the number of values returned.
  • This function processes field values as strings.

The order of the values is lexicographical.

Lexicographical order sorts items based on the values used to encode the items in computer memory. In Splunk software, this is almost always UTF-8 encoding, which is a superset of ASCII.

  • Numbers are sorted before letters. Numbers are sorted based on the first digit. For example, the numbers 10, 9, 70, 100 are sorted lexicographically as 10, 100, 70, 9.
  • Uppercase letters are sorted before lowercase letters.
  • Symbols are not standard. Some symbols are sorted before numeric values. Other symbols are sorted before or after letters.

Example

To illustrate what the values function does, let's start by generating a few simple results.

  1. Use the from and streamstats commands to generate a set of 11 results that are simply timestamps and a count of the results, which are used as row numbers. Empty arrays with the from command generate the timestamps.

    | from [{},{},{},{},{},{},{},{},{},{},{}] | streamstats count AS rowNumber

    There are 11 results. Th first few results look something like this:

    _time rowNumber
    2019-10-10T07:19:02.000-07:00 1
    2019-10-10T07:19:02.000-07:00 2
    2019-10-10T07:19:02.000-07:00 3
    2019-10-10T07:19:02.000-07:00 4
    2019-10-10T07:19:02.000-07:00 5

    Notice that each result appears on a separate row, with a line between each row.

  2. Add the stats command with thevalues function the the search. The results are returned in lexicographical order.

    | from [{},{},{},{},{},{},{},{},{},{},{}] | streamstats count AS rowNumber | stats values(rowNumber) AS numbers

    The results look something like this:

    numbers
    1
    10
    11
    2
    3
    4
    5
    6
    7
    8
    9

    Notice that this is a single result with multiple values. There are no lines between each value.

  3. Compare these results with the results returned by the list function.

See also

Function information
Overview of SPL2 stats and chart functions
Quick Reference for SPL2 Stats and Charting Functions
Naming function arguments in the SPL2 Search Manual
Evaluation functions for JSON and multivalue data
JSON functions
Multivalue eval functions
Last modified on 01 June, 2023
PREVIOUS
Event order functions
  NEXT
Time functions

This documentation applies to the following versions of Splunk® Cloud Services: current


Was this documentation topic helpful?


You must be logged into splunk.com in order to post comments. Log in now.

Please try to keep this discussion focused on the content covered in this documentation topic. If you have a more general question about Splunk functionality or are experiencing a difficulty with Splunk, consider posting a question to Splunkbase Answers.

0 out of 1000 Characters