Over a million developers have joined DZone.

Faceted navigation of data

DZone's Guide to

Faceted navigation of data

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

Faceted navigation is an efficient way of exploring a set of entities via the values of their attributes. You have probably already used it, maybe without knowing its name. For example, with a music program or on a shopping website. This post explains what faceted navigation is and what benefits it brings.

Faceted navigation combines a summary of those values with a way of selecting only those entities that have a given value. Faceted navigation is currently most prominently used in music programs. As an example, consider the following small database of songs:

Genre Artist Album Title
Rock Beatles Revolver Good Day Sunshine
Funk James Brown Cold Sweat Cold Sweat
Rock Beatles White Album I'm So Tired
Funk Prince Parade Kiss

Any of the columns taken as a set is a facet of these songs. Thus, the facet “Genre” has the values “Funk” and “Rock”. In faceted navigation, a facet plays two roles. First, it summarizes a set of faceted entities: For a set of songs, there are typically less genres than songs, making the list of genres a nice summary. Often a count of how often a given facet value appears is displayed in such a summary. This illustrates how the set of all entities is partitioned by a facet. Continuing the example, the facet-based summary below shows that the songs are half funk, half rock.

Genre Artist Album
Funk (2) Beatles (2) Cold Sweat (1)
Rock (2) James Brown (1) Parade (1)
  Prince (1) Revolver (1)
    White Album (1)

Not all facets make good summaries: The song title was left out, because there normally is almost a one-to-one mapping between song and song title. The facet “album” does not work well for the example, either (this is different in real-world music databases).

The second role a facet plays is for navigation. It is based on the observation mentioned above that facets partition the set of faceted entities. For navigation, facet values are interpreted as restrictions. Selecting a value shows only those entities where the facet has that value. After restricting the result set, one can continue to refine it by repeating the last two steps: One first computes the facet values as a summary of the restricted, smaller, set and then further restricts it by selecting from these values. For music, this kind of navigation is often hierarchical: One starts with genre, continues with artist, and then selects from the albums of that artist. But it works non-hierarchically, too. Several artists might collaborate for an album. Then it makes sense to look upwards in the “hierarchy”: Given an album, what are the artists?

Shopping websites frequently use tree-based navigation (but faceted navigation is becoming increasingly popular). Their trees force you into making you choices in a certain order: first choose shirt or pants, then choose male or female, then color. With faceted navigation, you can create the facets “function”, “gender”, “color” and start your choice at any of them. This can be seen as an on-demand generation of a tree, the remainder of this pseudo-tree is rearranged as you make your choices. Often, restrictions are shown in the order in which they have been made, for example:

color=blue, function=shirt, gender=male

This is like a path to the entities one currently sees. Note the similarity to tree paths, e.g. the path of the current directory in a file system.

Faceted navigation works well as a complement to text search. Searching for text among the entries is a form of restriction. The computed summary now tells the user where the text appeared (in which albums etc.).


Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat


Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}