• Start

Language Primitives

/

Data types

Sets

A set is a collection type of deduplicated and ordered values that can have a maximum size limit.

Note

Before version 3.0.0, sets were simply arrays that deduplicated their items. To emulate the former behaviour, add the clause VALUE $value.distinct() to a DEFINE FIELD definition.

A set is similar to an array, but with two key differences:

  • The values in a set are automatically deduplicated.

  • The values in a set are automatically ordered.

A set can be created using the literal syntax {}.

/**[test]

[[test.results]]
value = "{1, 2, 6}"

*/

RETURN {1, 6, 6, 2};
-- {1, 2, 6}

To create a set with zero items or a single item, add a comma.

/**[test]

[[test.results]]
value = "true"

[[test.results]]
value = "true"

[[test.results]]
value = "false"

[[test.results]]
value = "false"

*/
{,}.is_set();  -- true
{9,}.is_set(); -- true

{}.is_set();   -- false
{9}.is_set();  -- false

In addition to the {} literal syntax, an array can be cast into a set.

/**[test]

[[test.results]]
value = "NONE"

[[test.results]]
value = "NONE"

[[test.results]]
value = "[{ bank_accounts: [55555, 55555, 98787], id: customer:jud5qdgtehj5z1cv91e1, languages: {'en', 'ja', 'kr'} }]"
skip-record-id-key = true

*/

DEFINE FIELD bank_accounts ON TABLE customer TYPE array<int>;
DEFINE FIELD languages ON TABLE customer TYPE set<string>;

CREATE customer SET
    bank_accounts = [
      55555,
      55555,
      98787
    ],
    languages = <set>[
        "en",
        "ja",
        "kr",
        "kr"
    ];
Output
[
	{
		bank_accounts: [
			55555,
			98787
		],
		id: customer:uv6mn62t8td9vzvfogh4,
		languages: {
			'en',
			'ja',
			'kr'
		}
	}
]

Casting into a set and back into an array can be a convenient way to deduplicate items in the same way that the array::distinct() and array::sort() functions are used.

/**[test]

[[test.results]]
value = "[3, 4, 5, 6, 7, 9, 18]"

[[test.results]]
value = "[3, 4, 5, 6, 7, 9, 18]"

*/

<array><set>[18,7,6,6,6,6,5,4,3,9];
[18,7,6,6,6,6,5,4,3,9].distinct().sort();
Output
[3, 4, 5, 6, 7, 9, 18]

The [] index operator can be used on a set in the same manner as an array. Note however that due to a set's automatic ordering, its individual values are technically not assigned an index. This can be seen in the following example in which [0] for an array will return whichever item happens to be at that location, while for a set [0] will automatically be the item with the least value.

To return the greatest value of a set, use [$] (since 3.2.0) or the set::last() function.

/**[test]

[[test.results]]
value = "4"

[[test.results]]
value = "2"

[[test.results]]
value = "6"

[[test.results]]
value = "6"

*/

-- Array: returns 4 at index 0
[4,6,2][0];

-- Set: returns 2, the least item
(<set>{4,6,2})[0];

-- Set: returns 6, the greatest item
{4,6,2}[$];
{4,6,2}.last();

SurrealDB also includes a number of methods for sets that make it easier to filter and map. These methods take a closure (an anonymous function) that works in a similar way to the $this parameter above.

Here is an example of the set::filter() method being used. Note that the parameter name inside the closure is named by the user, so $val in the example below could be $v or $some_val or anything else.

/**[test]

[[test.results]]
value = "{3, 5}"

*/

{1,3,5}.filter(|$val| $val > 2);

-- {3,5}

An set can be added to another set or array, resulting in a single set consisting of the items of the first followed by those of the second.

/**[test]

[[test.results]]
value = "{1, 2, 3, 4}"

[[test.results]]
value = "{1, 2, 3, 4}"

*/

{1,2} + [3,4];
{1,2} + {3,4};
Output
{1,2,3,4}

Was this page helpful?