There are some use-cases where you want to provide the user with search suggestions. One of those examples would be creating tags. When the user starts typing for a tag, you want to give him some suggestions. This way, he doesn't need to type the whole word and can see whats offered. Such methods combined with libraries like select2
improve the overall user expirience alot.
In our example, we'll create an airport search. All the results will be displayed right away on the map. When the user starts typing, we'll suggest some airports to him.
Instead of describing the example, take a look at the demo so that you have a better understanding of what we're trying to do here.
Requirements
- Composer
- PHP >= 7.1
- PDO PHP Extension
- SQLite PHP Extension
- mbstring PHP Extension
- Laravel Framework
- TNTSearch 2.7
- Laravel Scout
Getting started
We won't cover the installation process of TNTSearch and Laravel Scout since it's rather straitforward, and its covered in the documentation for both packages. Our main focus here will be the idea behind.
Let's start with creating a command that will generate the index.
php artisan make:command CreateAirportsIndex
The command will look like this:
Let's see what's going on here and why we need to create the index like this. One unusual thing here is that we're going to use an "Egde ngram tokenizer"
Once the command is created, we need to run it:
php artisan create:search-suggestions
Edge ngram tokenizer
I think that this concept is best explained with an example. Consider, you have a text quick brown fox
. By using an edge gram tokenizer, the text will be broken into words and then into this:
[ qu, qui, quic, quick, br, bro, brow, brown, fo, fox]
All of those terms will be stored in the index, so when you start typing any substring of the word quick
, brown
or fox
it will find it in the index.
This will, of course, take some more disk space. In our example for 10k records of airports, the index size is 8MB
The next thing you need to pay attention in the above code is that, after we do the indexing, we put the tokenizer back to ProductTokenizer
. By default, TNTSearch will also break your search phrase into tokens, and in this case, we don't want to do this; we want to search exactly what is entered, so we change the tokenizer back to ProductTokenizer
.
Making the search
Since we're using Laravel scout, the search controller will be very clean:
The frontend will make an ajax request to this route when the user stops typing. And voila, there you have it - a simple app with search suggestions.
For more such tutorial, don't forget to follow