Looker Explore Best Practices: Labels, Joins, and Field Organization
How to design Looker Explores that business users actually understand. Covers labeling conventions, join best practices, field grouping, and documentation patterns.
Your Explores are the interface between your data model and your business users. A well-designed Explore makes self-service analytics possible. A poorly designed one generates a flood of Slack messages asking "which field do I use?"
Here's how to get them right.
Start With the Business User's Workflow
Before writing any LookML, ask: what questions will people ask this Explore? An Explore called order_items with 200 ungrouped fields is unusable. An Explore called "Customer Orders" with fields organized by Finance, Shipping, and Product categories — that's self-service.
explore: order_items {
label: "Customer Orders"
description: "Start here for order-level analysis. Includes customer demographics, product details, and shipping status."
group_label: "Sales"
join: customers {
type: left_outer
relationship: many_to_one
sql_on: ${order_items.customer_id} = ${customers.id} ;;
}
}
The description tells users when to use this Explore. The group_label organizes it in the menu. Both are skipped in 90% of the Looker instances we audit.
Labels: When to Use Them and When Not To
Most fields don't need labels. If the field name is already clear — order_id, created_date, status — adding a label just creates maintenance overhead.
Use labels when:
- The database column name is abbreviated or cryptic
- You need to align with business terminology
- The auto-generated label is misleading
dimension: usr_typ_cd {
label: "User Type" # Needed — database name is cryptic
}
dimension: order_id {
# No label needed — field name is already clear
}
Same rule applies to view labels:
view: itm_dtl {
label: "Item Detail" # Needed — view name is abbreviated
}
view: customers {
# No label needed — view name is clear
}
Field Grouping With group_label
Once an Explore has more than 20-30 fields, grouping becomes essential. Group by business domain, not by data type.
dimension: price {
group_label: "Order Finance"
label: "Item Price"
}
dimension: cost {
group_label: "Order Finance"
label: "Item Cost"
}
dimension: margin {
group_label: "Order Finance"
label: "Item Margin"
type: number
sql: ${price} - ${cost} ;;
}
This puts all financial fields together in the Explore sidebar. Users find what they need without scrolling through 100 fields.
Common grouping patterns:
- Order Finance, Order Status, Order Dates
- Customer Demographics, Customer Activity, Customer Lifetime
- Product Details, Product Categories, Product Metrics
Join Best Practices
Always Declare Relationships Correctly
This is the single most impactful join setting in Looker. Get it wrong and your measures will be incorrect — and users won't know.
explore: orders {
join: customers {
type: left_outer
relationship: many_to_one # Many orders belong to one customer
sql_on: ${orders.customer_id} = ${customers.id} ;;
}
join: order_items {
type: left_outer
relationship: one_to_many # One order has many items
sql_on: ${orders.id} = ${order_items.order_id} ;;
}
}
If you declare many_to_one when the actual relationship is one_to_many, Looker won't warn you — it'll just produce wrong numbers.
Every Joined View Needs a Primary Key
Without a primary key, Looker can't properly deduplicate rows. Every view in a join must have one:
view: orders {
dimension: order_id {
primary_key: yes
type: number
sql: ${TABLE}.order_id ;;
}
}
For tables without a natural primary key, create a composite key:
view: order_items {
dimension: composite_key {
primary_key: yes
hidden: yes
sql: ${order_id} || '-' || ${item_id} ;;
}
}
Field Sets for Drill Paths
Field sets define what users see when they click a value to drill down. Without them, Looker shows all fields — which is overwhelming.
set: order_details {
fields: [
order_id,
created_date,
status,
total_amount,
customer_name
]
}
measure: total_revenue {
type: sum
sql: ${amount} ;;
drill_fields: [order_details*]
}
Now when a user clicks a revenue number, they see a focused table of order details — not every field in the Explore.
Documentation That Actually Helps
Field Descriptions
Write descriptions that explain business meaning, not just data type:
# Bad
dimension: days_since_signup {
description: "Number type field"
}
# Good
dimension: days_since_signup {
description: "Days since customer first signed up. Customers with 0-30 days are considered 'New'. Used in retention cohort analysis."
type: number
sql: DATE_DIFF(CURRENT_DATE, ${signup_date}, DAY) ;;
}
Explore Descriptions
Tell users when to use this Explore, what data it includes, and what key filters to apply:
explore: sales {
description: "Use for analyzing sales performance. Includes customer demographics and product details. Filter by date range first — unfiltered queries are expensive. Key filters: order_date, product_category, region."
}
Let dbt Handle Descriptions
If you use dbt, write your field descriptions there — they flow automatically through BigQuery to Looker:
# In dbt schema.yml
models:
- name: orders
description: "Table containing all order information"
columns:
- name: order_id
description: "Unique identifier for each order"
- name: status
description: "Current status: Processing, Shipped, or Delivered"
Don't duplicate these descriptions in LookML. Only add Looker-specific context if needed (like drill behavior or filter recommendations).
Common Mistakes We See in Audits
- No descriptions on any Explore — users have no idea which one to use
- Wrong relationship declarations — measures return incorrect values
- Missing primary keys — joins produce duplicated rows
- No field grouping — 100+ ungrouped fields in the sidebar
- Labels on every field — maintenance nightmare with no benefit
- No drill paths defined — users can't explore data interactively
- Overly broad Explores — one Explore with 30 joins that answers every question (slowly)
A Checklist for Every Explore
Before deploying a new Explore, verify:
-
labelanddescriptionare set -
group_labelorganizes it in the menu - All joins have correct
relationshiptypes - All joined views have
primary_keydefined - Fields are organized with
group_label - Key measures have
drill_fields - Descriptions explain business meaning, not data types
- The Explore is tested with real user queries
Get the LookML Best Practices Guide + AI Skill
Our complete guide covers project structure, explores, permissions, caching, and more — plus a Claude skill that audits your LookML automatically.
Labs4Change has trained 16,000+ analytics engineers on Looker. Book a free LookML audit — we'll review your Explores, joins, and field organization in 30 minutes.