Skip to main content

Migrating Looker Explores to Holistics

High-level Overview​

Looker Explore vs Holistics Dataset​

In principle, an explore in Looker corresponds to a dataset in Holistics.

Looker Explore to Holistics Dataset

Dynamic Root Models vs. Root Models​

Looker's explore feature is a SQL generation interface that creates a series of JOINs based on the fields you select. The first table in the FROM clause of the generated query represents the initial view in Looker's explore (or in Holistics, we call it root model).

Looker root model

This means that, even when you only select fields in users view (via Field Picker UI), Looker will always generate the SQL starting from the root model events to users via your specified joins.




In Holistics, the table in the from clause is dynamic based on which fields are selected in the our Explore UI

Relationships over Joins​

A key distinction between Looker and Holistics lies in how they handle joins. Holistics uses relationships to automatically generate appropriate joins, whereas Looker requires users to pre-define the joins in advance within their explores.

Relationships over Joins

Step-by-Step Migration Tutorial​

Using UI to create Dataset​

After migrating Looker Views to Holistics Models, you can then create Dataset from these Models.

Follow the video guide below

Using Code to create Dataset​

Step 1: Set Up Your Environment​

  1. Open your Looker explore file
  2. Create a new Holistics dataset
  3. Create dataset object inside dataset file Dataset name { }
  4. Identify the connection name, all views, and their relationships

Step 2: Add Data Source Name to Your Dataset​

Unlike Looker where connections are defined at the model level, Holistics requires explicitly specifying the data source for each dataset. Check the connection property in your Looker model file and add it to your Holistics dataset:

Looker model file
connection: "warehouse" // Defined once at model level
include: "views/*.view"

explore: ecommerce {
view_name: order_items
join: products { ... }
join: orders { ... }
}
Holistics dataset file
Dataset ecommerce {
data_source_name: 'warehouse' // Required in each dataset
}

For more details on connection differences, see Conceptual Differences: Data Source Connection.

Step 3: Define Models​

List all models used in the explore:

// Looker
explore: ecommerce {
view_name: order_items
join: products { ... }
join: orders { ... }
}

// Holistics
Dataset ecommerce {
models: [
order_items,
products,
orders
]
}

Step 4: Convert Joins to Relationships​

From the Looker explore below, we can identify:

  • 5 views that will become models in Holistics: order_items, products, orders, merchants, and users
  • The relationships between these models:
    • order_items many-to-one products (via product_id)
    • order_items many-to-one orders (via order_id)
    • products many-to-one merchants (via merchant_id)
    • orders many-to-one users (via user_id)
// Looker
explore: order_items {
join: products {
type: left_outer
sql_on: ${order_items.product_id} = ${products.id} ;;
relationship: many_to_one
}
join: orders {
type: left_outer
sql_on: ${order_items.order_id} = ${orders.id} ;;
relationship: many_to_one
}
join: merchants {
type: left_outer
sql_on: ${products.merchant_id} = ${merchants.id} ;;
relationship: many_to_one
}
join: users {
type: left_outer
sql_on: ${orders.user_id} = ${users.id} ;;
relationship: many_to_one
}
}

In Holistics, we express these relationships using the relationship syntax. The arrow direction (>) indicates the many-to-one relationship:

// Holistics
Dataset ecommerce {
models: [
order_items,
products,
orders,
merchants,
users
]

relationships: [
// orders -> users (n-1)
relationship(orders.user_id > users.id, true),

// order_items -> orders (n-1)
relationship(order_items.order_id > orders.id, true),

// order_items -> products (n-1)
relationship(order_items.product_id > products.id, true),

// products -> merchants (n-1)
relationship(products.merchant_id > merchants.id, true),
]
}

Step 5: Handle Access Control​

In Looker

// Looker
access_filter: {
field: orders.merchant_id
user_attribute: merchant_id
}

In Holistics

Use Holistics Row-level Permission instead

Step 6: Test and Validate​

  1. Test common field combinations
  2. Verify join paths are correct
  3. Compare query results with Looker
  4. Test access controls

Reference Manual​

Property Mapping​

Looker PropertyHolistics PropertyNotes
view_nameN/AHolistics uses dynamic root model
joinrelationshipsDefine relationships between models
sql_onrelationship()Use relationship syntax
fieldsDataset ViewUse Dataset Custom View
access_filterRow-level PermissionUse Row-level Permission

Common Patterns​

  1. Dataset Organization

    // Looker - using view_name and joins
    explore: ecommerce {
    view_name: order_items
    join: products { ... }
    join: orders { ... }
    }

    // Holistics - list all models and their relationships
    Dataset ecommerce {
    models: [
    order_items,
    products,
    orders
    ]
    relationships: [
    relationship(order_items.product_id > products.id, true),
    relationship(order_items.order_id > orders.id, true)
    ]
    }
  2. Field Selection

    // Looker - using fields parameter
    explore: ecommerce {
    fields: [
    orders.id,
    orders.status,
    users.email
    ]
    }

    // Holistics - using Dataset View
    Dataset ecommerce {
    // ... other configurations

    view main {
    fields: [
    orders.id,
    orders.status,
    users.email
    ]
    }
    }

Detailed Feature Comparison​

LookML ParameterPurposeSupportHolistics Equivalent & Implementation
Structural Parameters
extendsThe extends parameter lets you build upon the content and settings from another Explore✅Holistics AML Extend
extension: requiredflags an Explore as requiring extension✔️
(partial)
Holistics doesn't support this exact concept but we can rebuild this via Function
fields: [field-ref]specify which fields from an Explore are exposed in the Explore UI✅Holistics Dataset Custom View
tags: ["string"]Specifies text that can be passed to other applications🕑
Coming Soon
Display Parameters
descriptionadd information about the Explore to the UI✅Dataset description: description: "your_description"
group_labelchange the default organization of the Explore menu✔️
(partially)
Holistics doesn't have the exact concept, but users can manually organize the Dataset to appropriate folders in Reporting layer
hidden: yes or noHides an Explore from the Explore menu❌
labelChanges the way an Explore appears in the Explore menu✅Holistics Dataset Label: label: "Your Dataset"
queryCreates a predefined query for users to select in an Explore's Quick Start menu❌
view_labelSpecifies how a group of fields from the Explore's base view will be labeled in the field picker❌
Filter Parameters
access_filterAdds user-specific filters to an Explore✅Holistics Row-level Permission
always_filterAdds filters a user can change, but not remove, to an Explore❌
case_sensitiveSpecifies whether filters are case-sensitive for an Explore❌
sql_always_where: sql-block ;;Inserts conditions into the query's WHERE clause that a user cannot change or remove❌
sql_always_having: sql-block ;;Inserts conditions into the query's HAVING clause that a user cannot change or remove❌
Join Parameters
always_join: [field-ref]forces one or more joins to be included in the SQL that Looker generates❌
join: identifierdefine the join relationship between an Explore and a view❌Holistics uses relationship instead of pre-defined joins
Query Parameters
cancel_grouping_fields: [field-ref]stop Looker from adding a GROUP BY clause to the SQL❌
from: view-refDetermines the view that will define the fields of an Explore❌Holistics doesn't have root model concept
persist_formodify the amount of time that cached query results are used❌
persist_withspecify a datagroup caching policy to use for that specific Explore❌
required_access_grants: [access-grant-ref]Limits access to the Explore to only users whose user attribute values match the access grants✔️
(partially)
Share Dataset with Explorers and Viewers to explore.
Check our "Dataset Sharing" document
sql_table_name: sql-block ;;Specifies the database table on which an Explore will be based❌
view_name: view-refSpecifies the view on which an Explore will be based❌Holistics doesn't have root model concept
Aggregate Table Parameters
aggregate_tablecreate aggregate tables that will minimize the number of queries required✅Aggregated Awareness (Pre-aggregate)
Refinement Parameters
final: yes or noIndicates that the current refinement is the final refinement allowed for the Explore❌

(*) Looker Parameters that are not mentioned in this table are generally not supported


Open Markdown
Let us know what you think about this document :)