Cube Logo0.33.23

Segments

Segments are predefined filters. You can use segments to define complex filtering logic in SQL. For example, users for one particular city can be treated as a segment:

YAML
JS
cubes:
  - name: users
    # ...

    segments:
      - name: sf_users
        sql: "{CUBE}.location = 'San Francisco'"

Or use segments to implement cross-column OR logic:

YAML
JS
cubes:
  - name: users
    # ...

    segments:
      - name: sf_users
        sql: >
          {CUBE}.location = 'San Francisco' OR
          {CUBE}.state = 'CA'

As with other cube member definitions, segments can be generated:

const userSegments = {
  sf_users: ["San Francisco", "CA"],
  ny_users: ["New York City", "NY"],
};

cube(`users`, {
  // ...

  segments: {
    ...Object.keys(userSegments)
      .map((segment) => ({
        [segment]: {
          sql: `${CUBE}.location = '${userSegments[segment][0]}' or ${CUBE}.state = '${userSegments[segment][1]}'`,
        },
      }))
      .reduce((a, b) => ({ ...a, ...b })),
  },
});

After defining a segment, you can pass it in query object:

{
  "measures": ["users.count"],
  "segments": ["users.sf_users"]
}

The name parameter serves as the identifier of a segment. It must be unique among all segments, dimensions, and measures within a cube and follow the naming conventions.

YAML
JS
cubes:
  - name: users
    # ...

    segments:
      - name: sf_users
        sql: "{CUBE}.location = 'San Francisco'"

The public property is used to manage the visibility of a segment. Valid values for public are true and false. When set to false, this segment cannot be queried through the API. Defaults to true.

YAML
JS
cubes:
  - name: users
    segments:
      - name: sf_users
        sql: "{CUBE}.location = 'San Francisco'"
        public: false

The sql parameter defines how a segment would filter out a subset of data. It takes any SQL expression that would be valid within a WHERE statement.

YAML
JS
cubes:
  - name: users
    # ...

    segments:
      - name: sf_users
        sql: "{CUBE}.location = 'San Francisco'"

As segments are simply predefined filters, it can be difficult to determine when to use segments instead of filters on dimensions.

Let's consider an example:

YAML
JS
cubes:
  - name: users
    # ...

    dimensions:
      - name: location
        sql: location
        type: string

    segments:
      - name: sf_users
        sql: "{CUBE}.location = 'San Francisco'"

In this case following queries are equivalent:

{
  "measures": ["users.count"],
  "filters": [{
    "member": "users.location",
    "operator": "equals",
    "values": ["San Francisco"]
  }]
}

and

{
  "measures": ["users.count"],
  "segments": ["users.sf_users"]
}

This case is a bad candidate for segment usage and a filter on a dimension works better here. users.location filter value can change a lot for user queries and users.sf_users segment won't be used much in this case.

A good candidate case for a segment is when you have a complex filtering expression which can be reused for a lot of user queries. For example:

YAML
JS
cubes:
  - name: users
    # ...

    segments:
      - name: sf_ny_users
        sql: >
          {CUBE}.location = 'San Francisco' OR
          {CUBE}.location like '%New York%'

Did you find this page useful?