Designing an omni-search
By: Guy Barner
Tags: Search, Product Management, User Experience, Design Patterns, UX

Designing an omni-search

We all know search. You have some entity (say, songs), which might have one or more attributes (name and album), and you search through them. But what when you’re not just searching for songs, but also for artists, playlists, or Genres? Guy Barner Jun 21·8 min read

You might build a separate search field for each entity, or you might combine them all into one input field. This is known as omni-search.

Omni-search is one of those features that can completely change the UX of a product. Since almost every product has search functionality, it’s definitely worth understanding the Omni option in depth. However, since search is, on the surface at least, a mear input box with a results dropdown, it seems deceivingly simple. I assure you, it is not.

I personally love omni-searches in products I use. I’ve built a few myself in previous products, and I just started working on one for my current product, tagbox.io. Doing so, I discovered that there are surprisingly few resources available on the web about it, which is what drove me to write this post.

Entity vs. attribute

First, a quick terminology overview. In search, an entity is what you search for, and an attribute is what you search it by. This can get confusing, as a search term can be both simultaneously. Sticking with the previous example, you can look for the Song entity by the attributes ‘name’ and ‘artist’. But you can also look for the Artist entity by the attributes ‘artist name’ and ‘songs’.

Typically, an entity will correspond to a table in your database, and the attributes will correspond with the fields of that table.

Examples of omni-search

First, let’s see a few great examples of omni-search, and how they impact the products.

Spotify

The prototypical example of omni-search, Spotify is great at helping you find what you’re looking for, and their results page probably the best there is.

On Spotify, you can look for 8 different entities: Songs, Artists, Albums, Playlists, Podcasts, Episodes, Profiles, and Genres. Could you imagine how the app would look with 8 input fields?

Medium

Don’t stop reading to test this! :)

On Medium, you can look for stories, people, publications, and tags. They take a unique approach in showing results, as I’ll show below.

FullStory

This is my personal favorite. FullStory, if you don’t know it, is a session recording tool for qualitative analytics. In my opinion, it's the best one out there by far, and omni-search is the main reason for it.

FullStory uses omni-search for filters, and it has about 30 of them. While you can go to filters > select filter > type your query, it’s infinitely easier to just type what you’re looking for and have the omni-search find it.

type in an email address, and FullStory will suggest users with that email. Type a CSS selector, and they’ll suggest ‘clicked on’. And that’s the magic of omni-search — when done right, you get a feeling that the app can read your mind.

Designing omni-search

Searchable entities

The first thing you need in order to build your omni-search, is to map the entities users might be searching for. Remember: it’s not what they search it by — just what they’d like to find.

You might not be sure what’s considered ‘an entity’. For example, on Google Drive, you can search for PDFs, Sheets, or Docs. Are these different entities? While there’s a technical discussion I won’t get into, as a rule of thumb, if all candidates share the same attributes (e.g. doc name, creator, date…) — then it can be considered the same entity with a ‘type’ attribute.

Searchable attributes

Once you’ve selected the entities to be searched, let’s select the attributes that the users can search by. Don’t be tempted to use all available attributes — this will slow performance and produce bad results. Instead, only use the attributes your users are likely to use. If you’re not sure, guess, and then go back after the release and see what your users have tried searching by.

Example: on Spotify, each artist has an ‘about’ attribute, which you can see after you’ve clicked on the artist (all the way on the bottom). However, if you tried copy-pasting that ‘about’ text to the omni-search, you won’t find the artist, because Spotify doesn’t search artists by the ‘about’ attribute, which makes sense: it’s unlikely anyone will try searching by it, in any reasonable use-case.

Search behavior

There are a few other parameters you need to define in your search:

Substring location:

Let’s take The Chainsmokers. Which of these search terms do you think should find them: ‘the chain’, ‘chain’, or ‘smokers’?

If you guessed all three, then you’re right. But that’s not always the case. Let’s try to look for the Medium publication Noteworthy. You’ll find it if you search for ‘notew’, but not if you look for ‘worthy’.

This has a lot to do with how the data is being indexed, and there are three main options to choose from:

start of string (e.g. ‘the chain’) start of each word (e.g. ‘chains’) all substrings (e.g. ‘smokers’, or ‘ainsmoke’)

Again, more is not always better. Pick the one most suited to what your users are likely to search.

Strict vs. fuzzy search

Users make mistakes. They might type in “the chansmokers”, leaving out the ‘i’, either due to a typo or miss-spelling. A fuzzy search will catch that. Too fuzzy of a search will also catch a lot of garbage results.

Start of search

Most searches don’t show results until you type in at least 2–3 letters.

Debounce

We type quickly. You don’t want each keystroke to start a new search, because that would seem jumpy to the user. You commonly wait 0.1s or so after the keystroke (don’t hold me to that number), to make sure the user stopped typing.

capitalization

Not much to say about this. 99% of searches should be case insensitive.

Scores and weights

This part is a bit complicated, and can fill an entire post on its own, but I’ll try to explain the gist of it:

In very simple searches, the search term is either found, or not found. 1 or 0. With more modern search tools (Elasticsearch being the most popular), each result gets a score, based on the location of the substring, accuracy, and a few other parameters.

To add to that, it’s possible to put weights on those scores. Say you search for a song by both track name and artist. The term ‘young’ can find Young Folks by Peter, Bjorn and John, and it can also find Heart of Gold by Neil Young. However, when looking for songs, it makes sense to give more weight to the name of the song than to the artist (and of course, vice-versa when you’re looking for artists).

Showing results

Here’s when the fun starts! Results can be shown in 3 basic formats:

quick preview — a popup showing around 10 top results result summary — a full page showing the main results for each entity all results — all of the results of a specific entity

Not all apps use all 3 formats. The Facebook example shown above does use all three, but Medium skips the ‘result summary’ and goes from ‘quick preview’ to ‘all results’ of a specific entity. Spotify, on the other hand, skips the ‘preview popup’ and shows the results in a ‘result summary’ page, then allowing the ‘all results’ drill-down.

Other things to consider when showing results

when clicking on search, and before typing, consider showing a ‘recent searches’ or ‘popular searches’ for easy selection.

When showing results, you can group them by entity, so that the songs are separate from the artists, for example. An alternative to that would be to show them by search relevance, in which case you might show an artist, then a song, and then another artist, according to how well they matched the query. This is how they do it in FullStory, and it’s outstanding for their specific use case. It makes sense there because there are many entities, so grouping by them will mean way too many results.

If you choose to group the results by entity, you still need to decide whether to always show them in the same order for consistency, or to set the order of the groups by relevance.

Depending on the choices you made in previous sections, you’ll need to decide on the look of the result cards. If you’re not grouping by entity, you’ll need to have icons for each entity for ease of use. In other cases, you’ll probably want to have 2–3 attributes on the card. For example, under album results, Spotify shows the artist’s name, the album’s name, and the album’s cover.

Marking the query string in your results is really great, but it brings with it a new brain-twister: what if your entity has 5 searchable attributes, but the results card only shows 3 of them? In that case, you might find a result but not show that attribute on the card! One alternative is to have one ‘flexible’ attribute on the card, so that you always end up showing where you found the search term. In the above example, that might mean that on an album result, you might show the cover, album name, and the date of release instead of the artist’s name. This would hurt consistency and might hide important information, so think about the best solution for your use case.

Summary

Omni-search is one of those features that look simple at first glance, but are actually super-complex when you start digging into them. I wanted to show all of the different variations and design choices we make while designing it, but don’t forget that at the end of the day — it’s all about finding what you’re looking for.