Skip to content

Commit

Permalink
Update examples and docs
Browse files Browse the repository at this point in the history
  • Loading branch information
jonatas committed Dec 9, 2024
1 parent 05a5334 commit 81d2f97
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 54 deletions.
40 changes: 12 additions & 28 deletions docs/toolkit.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,40 +197,29 @@ Measurement

As you can see, it's much easier to read and digest the example. Now, let's take
a look in how we can generate the queries using the scopes injected by the
`acts_as_time_vector` macro.
`acts_as_hypertable` macro.


## Adding the `acts_as_time_vector` macro
## Configuring the `segment_by` and `value_column`

Let's start changing the model to add the `acts_as_time_vector` that is
here to allow us to not repeat the parameters of the `timevector(ts, val)` call.
Let's start changing the model to change the `acts_as_hypertable` to use the
`segment_by` and `value_column` options.

```ruby
class Measurement < ActiveRecord::Base
self.primary_key = nil

acts_as_hypertable time_column: "ts"

acts_as_time_vector segment_by: "device_id",
value_column: "val",
time_column: "ts"
end
acts_as_hypertable time_column: "ts",
segment_by: "device_id",
value_column: "val"
end
```

If you skip the `time_column` option in the `acts_as_time_vector` it will
inherit the same value from the `acts_as_hypertable`. I'm making it explicit
here for the sake of making the macros independent.


Now, that we have it, let's create a scope for it:

```ruby
class Measurement < ActiveRecord::Base
acts_as_hypertable time_column: "ts"
acts_as_time_vector segment_by: "device_id",
value_column: "val",
time_column: "ts"
acts_as_hypertable time_column: "ts",
segment_by: "device_id",
value_column: "val"

scope :volatility, -> do
select(<<-SQL).group("device_id")
Expand All @@ -248,16 +237,11 @@ end
Now, we have created the volatility scope, grouping by device_id always.

In the Toolkit helpers, we have a similar version which also contains a default
segmentation based in the `segment_by` configuration done through the `acts_as_time_vector`
macro. A method `segment_by_column` is added to access this configuration, so we
can make a small change that makes you completely understand the volatility
macro.
segmentation based in the `segment_by` configuration done through the `acts_as_hypertable` macro. A method `segment_by_column` is added to access this configuration, so we can make a small change that makes you completely understand the volatility scope.

```ruby
class Measurement < ActiveRecord::Base
# ... Skipping previous code to focus in the example

acts_as_time_vector segment_by: "device_id",
acts_as_hypertable segment_by: "device_id",
value_column: "val",
time_column: "ts"

Expand Down
19 changes: 5 additions & 14 deletions docs/toolkit_candlestick.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ The model is the best place to describe how you'll be using the timescaledb to k

```ruby
class Tick < ActiveRecord::Base
acts_as_hypertable time_column: :time
acts_as_time_vector value_column: :price, segment_by: :symbol
acts_as_hypertable time_column: :time,
segment_by: :symbol,
value_column: :price

scope :ohlcv, -> do
select("symbol,
Expand Down Expand Up @@ -108,26 +109,16 @@ The `acts_as_hypertable` macro will assume the actual model corresponds to a hyp
* `.hypertable` will give you access to the [hypertable][hypertable] domain, the `table_name` will be used to get all metadata from the `_timescaledb_catalog` and combine all the functions that receives a hypertable_name as a parameter.
* The `time_column` keyword argument will be used to build scopes like `.yesterday`, `.previous_week`, `.last_hour`. And can be used for your own scopes using the `time_column` metadata.

The `acts_as_time_vector` will be offering functions related to timescaledb toolkit.

The `value_column:` will be combined with the `time_column` from the hypertable to use scopes like `candlestick`, `volatility`, `lttb` and just configure the missing information.

The `segment_by:` will be widely used in the scopes to group by the data.

When the keywords `time_column`, `value_column` and `segment_by` are used in the `acts_as_{hypertable,time_vector}` modules.

By convention, all scopes reuse the metadata from the configuration. It can facilitate the process of building a lot of hypertable abstractions to facilitate the use combined scopes in the queries.

### The `acts_as_hypertable` macro

The `acts_as_hypertable` will bring the `Model.hypertable` which will allow us to use a set of timeseries related set what are the default columns used to calculate the data.

### The `acts_as_time_vector` macro

The `acts_as_time_vector` will allow us to set what are the default columns used to calculate the data. It can be very handy to avoid repeating the same arguments in all the scopes.

It will be very powerful to build your set of abstractions over it and simplify the maintenance of complex queries directly in the database.

### The `continuous_aggregates` macro

The `continuous_aggregates` macro will allow us to create continuous aggregates for the model. Generating a new materialized view for each scope + timeframe that will be continuously aggregated from the raw data.
Expand Down Expand Up @@ -162,9 +153,9 @@ If you need to generate some data for your table, please check [this post][2].

## Query data

When the `acts_as_time_vector` method is used in the model, it will inject several scopes from the toolkit to easily have access to functions like the `_candlestick`.
When the `acts_as_hypertable` method is used in the model, it will inject several scopes from the toolkit to easily have access to functions like the `_candlestick`.

The `candlestick` scope is available with a few parameters that inherits the configuration from the `acts_as_time_vector` declared previously.
The `candlestick` scope is available with a few parameters that inherits the configuration from the `acts_as_hypertable` declared previously.

The simplest query is:

Expand Down
5 changes: 3 additions & 2 deletions docs/toolkit_lttb_tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,9 @@ The `conditions` is the time-series data we'll refer to here.

```ruby
class Condition < ActiveRecord::Base
acts_as_hypertable time_column: "time"
acts_as_time_vector value_column: "temperature", segment_by: "device_id"
acts_as_hypertable time_column: "time",
segment_by: "device_id",
value_column: "temperature"
belongs_to :location, foreign_key: "device_id"
end
```
Expand Down
9 changes: 5 additions & 4 deletions docs/toolkit_lttb_zoom.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,9 @@ The `conditions` is the time-series data we'll refer to here.

```ruby
class Condition < ActiveRecord::Base
acts_as_hypertable time_column: "time"
acts_as_time_vector value_column: "temperature", segment_by: "device_id"
acts_as_hypertable time_column: "time",
segment_by: "device_id",
value_column: "temperature"
belongs_to :location, foreign_key: "device_id"
end
```
Expand Down Expand Up @@ -217,7 +218,7 @@ def downsampled
end
```

The `segment_by` keyword explicit `nil` because we have the `segment_by` explicit in the `acts_as_time_vector` macro in the model that is being inherited here. As the filter is specifying a `device_id`, we can skip this option to simplify the data coming from lttb.
The `segment_by` keyword explicit `nil` because we have the `segment_by` explicit in the `acts_as_hypertable` macro in the model that is being inherited here. As the filter is specifying a `device_id`, we can skip this option to simplify the data coming from lttb.

!!!info "The lttb scope"
The `lttb` method call in reality is a ActiveRecord scope. It is encapsulating all the logic behind the library. The SQL code is not big, but there's some caveats involved here. So, behind the scenes the following SQL query is executed:
Expand All @@ -238,7 +239,7 @@ The `segment_by` keyword explicit `nil` because we have the `segment_by` explici
) AS ordered
```

The `acts_as_time_vector` macro makes the `lttb` scope available in the ActiveRecord scopes allowing to mix conditions in advance and nest the queries in the way that it can process the LTTB and unnest it properly.
The `acts_as_hypertable` macro makes the `lttb` scope available in the ActiveRecord scopes allowing to mix conditions in advance and nest the queries in the way that it can process the LTTB and unnest it properly.

Also, note that it's using the `->` pipeline operator to unnest the timevector and transform the data in tupples again.

Expand Down
12 changes: 6 additions & 6 deletions docs/toolkit_ohlc.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ As we don't need a primary key for the table, let's set it to nil. The
`acts_as_hypertable` macro will give us several useful scopes that can be
wrapping some of the TimescaleDB features.

The `acts_as_time_vector` will allow us to set what are the default columns used
to calculate the data.
The `acts_as_hypertable` will allow us to set what are the default columns used to calculate the data.


```ruby
class Tick < ActiveRecord::Base
self.primary_key = nil
acts_as_hypertable time_column: :time
acts_as_time_vector value_column: price, segment_by: :symbol
acts_as_hypertable time_column: :time,
segment_by: :symbol,
value_column: :price
end
```

Expand All @@ -59,12 +59,12 @@ If you need to generate some data for your table, please check [this post][2].

## The 'candlestick' scope

When the `acts_as_time_vector` method is used in the model, it will inject
When the `acts_as_hypertable` method is used in the model, it will inject
several scopes from the toolkit to easily have access to functions like the
candlestick.

The `candlestick` scope is available with a few parameters that inherits the
configuration from the `acts_as_time_vector` declared previously.
configuration from the `acts_as_hypertable` declared previously.

The simplest query is:

Expand Down

0 comments on commit 81d2f97

Please sign in to comment.