# CubDB.select

`select`

, go back to CubDB module for more information.
## Specs

select(GenServer.server(), [select_option()]) :: {:ok, any()} | {:error, Exception.t()}

Selects a range of entries from the database, and optionally performs a pipeline of operations on them.

It returns `{:ok, result}`

if successful, or `{:error, exception}`

if an
exception is raised.

## Options

The `min_key`

and `max_key`

specify the range of entries that are selected. By
default, the range is inclusive, so all entries that have a key greater or
equal than `min_key`

and less or equal then `max_key`

are selected:

```
# Select all entries where "a" <= key <= "d"
CubDB.select(db, min_key: "b", max_key: "d")
```

The range boundaries can be excluded by setting `min_key_inclusive`

or
`max_key_inclusive`

to `false`

:

```
# Select all entries where "a" <= key < "d"
CubDB.select(db, min_key: "b", max_key: "d", max_key_inclusive: false)
```

Any of `:min_key`

and `:max_key`

can be omitted, to leave the range
open-ended.

```
# Select entries where key <= "a"
CubDB.select(db, max_key: "a")
```

As `nil`

is a valid key, setting `min_key`

or `max_key`

to `nil`

does NOT
leave the range open ended:

```
# Select entries where nil <= key <= "a"
CubDB.select(db, min_key: nil, max_key: "a")
```

The `reverse`

option, when set to true, causes the entries to be selected and
traversed in reverse order.

The `pipe`

option specifies an optional list of operations performed
sequentially on the selected entries. The given order of operations is
respected. The available operations, specified as tuples, are:

`{:filter, fun}`

filters entries for which`fun`

returns a truthy value`{:map, fun}`

maps each entry to the value returned by the function`fun`

`{:take, n}`

takes the first`n`

entries`{:drop, n}`

skips the first`n`

entries`{:take_while, fun}`

takes entries while`fun`

returns a truthy value`{:drop_while, fun}`

skips entries while`fun`

returns a truthy value

Note that, when selecting a key range, specifying `min_key`

and/or `max_key`

is more performant than using `{:filter, fun}`

or `{:take_while | :drop_while, fun}`

, because `min_key`

and `max_key`

avoid loading unnecessary entries from
disk entirely.

The `reduce`

option specifies how the selected entries are aggregated. If
`reduce`

is omitted, the entries are returned as a list. If `reduce`

is a
function, it is used to reduce the collection of entries. If `reduce`

is a
tuple, the first element is the starting value of the reduction, and the
second is the reducing function.

The `timeout`

option specifies a timeout (in milliseconds or `:infinity`

,
defaulting to `:infinity`

) after which the operation will fail.

## Examples

To select all entries with keys between `:a`

and `:c`

as a list of `{key, value}`

entries we can do:

`{:ok, entries} = CubDB.select(db, min_key: :a, max_key: :c)`

If we want to get all entries with keys between `:a`

and `:c`

, with `:c`

excluded, we can do:

```
{:ok, entries} = CubDB.select(db,
min_key: :a, max_key: :c, max_key_inclusive: false)
```

To select the last 3 entries, we can do:

`{:ok, entries} = CubDB.select(db, reverse: true, pipe: [take: 3])`

If we want to obtain the sum of the first 10 positive numeric values
associated to keys from `:a`

to `:f`

, we can do:

```
{:ok, sum} = CubDB.select(db,
min_key: :a,
max_key: :f,
pipe: [
map: fn {_key, value} -> value end, # map values
filter: fn n -> is_number(n) and n > 0 end # only positive numbers
take: 10, # take only the first 10 entries in the range
],
reduce: fn n, sum -> sum + n end # reduce to the sum of selected values
)
```