Custom Facets and GREL
Last updated on 2025-11-18 | Edit this page
Estimated time: 0 minutes
Overview
Questions
- When do we need a custom facet instead of a built-in one?
- How can GREL help us filter or transform data more flexibly?
Objectives
- Understand what a custom facet is and how it differs from standard
facets.
- Learn to write simple GREL expressions for filtering and
transformation.
- Apply a custom facet on the Artist column to distinguish between single and multiple creators.
So far, we have explored facets that you can create by clicking through the menu—text, numeric, and timeline facets. These are powerful, but sometimes our exploration or cleaning task needs a rule that isn’t built in. In those cases, OpenRefine lets us define our own facets using GREL (General Refine Expression Language).
GREL looks like code, but many useful expressions are short and
readable. You can think of them as tiny instructions that tell
OpenRefine how to interpret or transform the value currently in a cell
(that value is referred to as value inside GREL). Every
funciton we already used could be written in GREL as well, but to make
things eaisier the most common functions are already built it.
If, for example, we now want to examine our data set to see which works of art were created by only one or by then one, we could create a custom facet to filter by this criteria.
Question: How could we filter the column to find out whether one or more people were involved in creating a work of art??
Look at the column and consider how cells that contain one or more values differ. We can then use GREL to filter based on this difference.
What Is GREL?
GREL stands for General Refine Expression
Language.
It is a small, specialized language used inside OpenRefine to:
- inspect cell values
- transform text and numbers
- check conditions
- extract patterns
- create new values on the fly
Even though GREL looks a bit like programming, most expressions are
short, simple, and intuitive.
You don’t need prior coding experience. GREL is designed to help you
express small, precise rules for working with messy data.
Every OpenRefine transformation you perform through the menu could
also be written in GREL.
The menu, we are using, simply provides shortcuts for the most common
actions.
Creating a Custom Facet with GREL
Open the column menu for
Artist.Choose Facet → Custom text facet…
-
In the dialog, type the following GREL expression:
value.contains(",")This asks, “Does the cell contain a comma?” For each row, OpenRefine evaluates the expression and returns either
trueorfalse. Click OK. In the left panel, you now see a facet with two buckets:
trueandfalse.
That’s it—you just created a logic-based facet that the standard menus couldn’t provide.
Why this works: A Custom Facet runs your expression
on every row, groups the results, and lets you filter by the outcome.
You can write tests that return booleans
(true/false), strings (e.g., normalized
categories), or even numbers—OpenRefine will facet whatever the
expression returns.
Example: Detecting Unusually Long Titles
Another common task during data exploration is to identify values that might need attention based on their length. Very long artwork titles may indicate:
- combined fields
- metadata copied incorrectly
- multiple titles in one cell
- comments included inside the field
We can create a custom facet to group titles into “short” and “long” categories.
Open the column menu for
TitleChoose Facet → Custom text facet…
-
Enter this GREL expression:
if(value.length() > 40, "long title", "short title")
This expression checks the length of each title: - If the title has
more than 40 characters → "long title"
- Otherwise → "short title"
OpenRefine will show two groups: - long title
- short title
This allows you to quickly check whether unexpectedly long titles need to be cleaned, split, or reviewed.
You can adjust the number (40) depending on what makes sense for your dataset.
In this example, we use a more complex GREL expression:
if(value.length() > 40, "long title", "short title")
Compared to the earlier expression
(value.contains(",")), this one does more than simply check
the cell’s content and return true or false.
Here, the expression not only inspects the value but
also creates a new category based on a condition.
This expression works in two steps:
Inspect the cell:
value.length()calculates how many characters the title contains.-
Produce a new output:
Theif()function checks whether the condition is true (value.length() > 40).- If true → it returns
"long title". - If false → it returns
"short title".
- If true → it returns
What’s important is that these two labels do not
exist in the dataset.
They are created entirely by the GREL expression, and
OpenRefine then groups rows based on these newly generated values.
This shows a key idea of custom facets:
Custom facets do not have to group by the original cell contents; they can group by computed values that you define using GREL.
That is why the expression in this example includes more than just
value. We are not only checking the cell, but actively
creating a classification that helps us explore the data.
Callout: GREL-Functions
-
value.toLowercase()– lowercase the text. -
value.toUppercase()– uppercase the text. -
value.trim()– remove spaces at start/end. -
value.length()– number of characters. -
value.contains("text")–trueif “text” occurs. -
value.startsWith("A"),value.endsWith(".")– prefix/suffix checks. -
value.replace("old","new")– literal replace. -
value.replace(/\s+/," ")– regex replace (collapse multiple spaces). -
value.split(";")– split into an array on;. -
array.join("|")– join array back to a string. -
value.toNumber()– parse numbers (non-numeric becomes blank). -
value.toDate()– parse dates (useful before Timeline facets). -
value.toString()– convert back to text. -
isBlank(value)–truefor empty/whitespace-only. -
isNull(value)–truefor null values (missing). -
type(value)– returns “string”, “number”, “date”, etc. -
value.toDate()– parse a date (from strings like1954-05-01). -
value.toDate().toString("yyyy")– format the date to year. -
now()– current date/time (useful for comparisons).
- Custom facets group data using computed results
from a GREL expression, not only the original cell values.
- GREL is a lightweight language that allows you to inspect,
transform, and classify data inside OpenRefine.
- Custom facets let you ask flexible questions about your data, such
as identifying multiple creators or unusually long titles.
- With conditional expressions like
if(), you can define new categories that support deeper exploration and data-quality checks.