Implementing search with Django, Elasticsearch, and Vue.js
By: Fatime Selimi
Tags: Django Rest Framework, Vuejs, Django, Docker, Elasticsearch

Implementing search with Django, Elasticsearch, and Vue.js

In this short tutorial, I am going to show an example of how to implement a search feature using Elasticsearch with Django and Vue.js.

In the web application that we will create, users can add new articles by providing a title and the content of the article, and some tags if they want. They can also search for articles from the “Articles list”.

Assuming that you already know what Elasticsearch is and why we need it (since you stumbled upon this article in your searches), I will not go into details of explaining Elasticsearch. In short, Elasticsearch is a database that offers powerful search capabilities such as full-text search, fuzzy text search, etc. We will be using Elasticsearch to power our search feature in this web application. If you’re interested in learning more about Elasticsearch, this would be a good start: https://www.elastic.co/what-is/elasticsearch

The example application would look something like the GIF below. As mentioned above, we can add articles using the “New article” form at the bottom of the page or search for the articles using the search bar.

Search feature using Elasticsearch

The full code for this example web application can be found in this GitHub repo.

We will build our application by following these steps:

1.Create a new virtual environment

Let’s start by creating a new virtual environment. By doing this, we will isolate our Django setup on a per-project basis, thus any change that we make to our project will not affect other projects that we might also be developing.

In your terminal, run the commands shown below to create a new directory and change the current directory to the new project directory that we just created.

mkdir elastico-app cd elastico-app

Once we have created and are inside the new directory, we are ready to create our new virtual environment by running this command:

python3 -m venv env

And finally, we need to activate the new virtual environment like this:

source env/bin/activate

2.Install Django

Now we can install our preferred Django version. In this example, we will install Django 3.1.4.

(env) ~/elastico-app$ pip install Django==3.1.4

3.Create a new Django project and a new Django application

Next, let’s create a new Django project. We will call this project django_elasticsearch, and we will create it by running the following:

(env) ~/elastico-app$ django-admin startproject django_elasticsearch

Next, we will create a new Django application. We will call this application django_formset_vuejs and we will create it like this:

(env) ~/elastico-app$ python manage.py startapp django_elastico_vuejs

After we have successfully created our new application we have to add it to INSTALLED_APPS inside settings.py file.

Note: We also have to add ‘rest_framework’ in the INSTALLED_APPS. So the INSTALLED_APPS list at this point would look like below:

INSTALLED_APPS = [

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles', 'rest_framework',

'django_elastico_vuejs',

]

And our project tree should look like this:

elastico-app

├── django_elastico_vuejs

│ ├── admin.py

│ ├── apps.py

│ ├── migrations

│ │ └── __init__.py

│ ├── models.py

│ ├── tests.py

│ └── views.py

├── manage.py

├── django_elasticsearch

│ ├── __init__.py

│ ├── settings.py

│ ├── urls.py

│ └── wsgi.py

└── env

4. Create API models & Create Elasticsearch model

First, we will need to define REST API models so that we have a clear interface between REST API users and our REST API servers.

Next, we will need to define an Elasticsearch document which we will use to represent the searchable data that we will store in the Elasticsearch.

In this way, both interfaces can evolve separately.

Let’s save the models in a new “models” folder, under django_elastico_vuejs app.

4.1 REST API Models

Model objects:

Article()

ArticleRequest ()

() SearchArticleRequest()

Model serializers:

ArticleSerializer()

ArticleRequestSerializer()

SearchArticleRequestSerializer()

4.2 Elasticsearch document

Define ArticleDocument() as our Elasticsearch document and initiate it using the init() method.

Note: ArticleDocument inherits from Document class of elasticsearch_dsl library.

And the project tree:

elastico-app

├── django_elastico_vuejs

│ ├── migrations

│ ├── models

│ │ └──api

│ │ ├── __init__.py

│ │ └── models.py

│ │ └──es

│ │ ├── __init__.py

│ │ └── models.py

│ │ └── __init__.py

│ ├── __init__.py

│ ├── admin.py

│ ├── apps.py

│ ├── models.py

│ ├── tests.py

│ └── views.py

├── manage.py

├── django_elasticsearch

│ ├── __init__.py

│ ├── settings.py

│ ├── urls.py

│ └── wsgi.py

└── env

5. Set up Elasticsearch & Kibana servers using Docker

We initiate locally the Elasticsearch database using the Docker Compose tool in order to run the Elasticsearch from a docker image.

In addition, we also use Kibana as a data visualization tool for Elasticsearch, thus we have defined a Kibana container in the Docker Compose script as well.

This is how our docker-compose.yml file looks:

To run this Docker Compose file open your terminal and run this command:

(env) ~/elastico-app$ docker-compose up

Note: Make sure that you have installed Docker Desktop and it is running in your machine before trying to run this command, otherwise you’ll encounter issues executing the script docker-compose.

Kibana dashboard can be accessed from the browser using the port that we defined in the docker-compose file, i.e. 5601. For example, when typing http://localhost:5601/app/kibana#/dev_tools/console in the browser’s search bar we see Kibana’s UI similar to the screenshot below.