Imagine you are building an inventory or an ecommerce website or a social media of your own, what are the two major things you will have to deal with? A. Database B. Search engine
This article deals with building a simple app where we search for movies, to achieve this we use:
1. Meilisearch- for building the search and
2. Appwrite - for the backend to store data and run functions to automate the search
What is Appwrite?
Appwrite is a self-hosted backend-as-a-service platform that provides developers with all the core APIs required to build any application. Appwrite provides you with a set of APIs, tools, and a management console UI to help you build your apps a lot faster and in a much more secure way. Appwrite takes the heavy lifting for developers and handles user authentication and authorization, databases, file storage, cloud functions, webhooks, and much more!
What is Meilisearch?
Meilisearch is a powerful, fast, open-source, easy to use and deploy search engine. Both searching and indexing are highly customizable. Features such as typo-tolerance, filters, and synonyms are provided out-of-the-box. For more information about features go to our documentation
Prerequisites
Now that you have been introduced to Appwrite and Meilisearch, let’s start building with it. Before that, let’s make sure you have everything we need. Here’s the prerequisites:
- An IDE of your choice
- Latest version of Node.js
- Docker
- Appwrite installed
- Meilisearch installed
Building The Application
Let's get started building! Are you ready?
Getting Started With Meilisearch
For this demo, we used the meilisearch quickstart tutorial as a reference.
To install Meilisearch on your machine you can do it using Docker or a package manager depending on your OS.
Alternatively, you can also deploy Meillisearch on a cloud service
Note: Since I am on a Mac machine I used homebrew to install Meilisearch with the following command:
brew update && brew install meilisearch
Getting Started With Appwrite
To install Appwrite you need to have Docker installed and then run the following command to install:
docker run -it --rm \ --volume /var/run/docker.sock:/var/run/docker.sock \ --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \ --entrypoint="install" \ appwrite/appwrite:0.15.3
Alternatively, you can also go for one-click setups using Gitpod or Digital Ocean.
Creating a Project
After installing, Appwrite will be running on localhost and you should see a screen like this:
Clicking on
Create Project
, enterDemo
as the name and click onCreate
.
This is how your Appwrite console will look:
Next, let's set up the database and collection for the search application.
Creating a Database and Collection
A database in Appwrite is a group of collections for managing data. To create a database, visit the Database section:
- Click on
Create Database
- Enter
Movies
as the name - Click Create
For the collection:
- Click on Create Collection
- Enter
Movie details
as the name - Click Create
We also want to configure permissions for the collection for read/write access. For Movie details
, you’ll choose Document Level permissions. You can choose more granular permissions depending on your use case. The permissions page has more details on permissions so the user keeps ownership of their data.
Creating Document Attributes
Attributes can be defined as strings, numbers, emails, and more.
To create an attribute:
- Click on
Create Attribute
. - Select the type of Attribute to create.
- Use the table below to create the necessary attributes for chat.
Attribute id | Size |
---|---|
title | 255 |
id | 255 |
overview | 10000 |
genres | 255 |
Note- The attribute type will be string for all the attributes
Uploading Data to Appwrite
The movie data that we will use for this example is movies.json.
To upload it in Appwrite database we will be using a script.
Make a new dataWriter.js
file and paste the following code:
const { Client, Databases } = require("node-appwrite");
const fs = require("fs");
const movies = require("./movies.json");
const dotenv = require('dotenv');
// Init SDK
let client = new Client();
dotenv.config();
client
.setEndpoint(process.env.APPWRITE_ENDPOINT) // Your API Endpoint
.setProject(process.env.APPWRITE_PROJECTID) // Your project ID
.setKey(process.env.APPWRITE_KEY) // Your secret API key
.setSelfSigned(); // Use only on dev mode with a self-signed SSL cert
let databases = new Databases(client, "YOUR_DATABASE_ID");
//let promise = database.getDocument('627e9b5e008ffd8382ff', '6283ccb7773a9474319d')
// Run this until you are happy with the number of documents
const movieWrite = async () => {
console.log('starting addition of documents to db')
for (const movie of movies) {
const response = await databases.createDocument("YOUR_COLLECTION_ID", String(Math.random()), {
title: String(movie.title || Math.random()),
id: String(movie.id || Math.random()),
overview: String(movie.overview || Math.random()),
genres: String(movie.genres || Math.random()),
})
console.log(`Added ${movie.title}`, response);
await new Promise(resolve => setTimeout(resolve, 100));
}
}
movieWrite();
Storing your Appwrite secrets
Make a .env file as the following and put in your Appwrite secrets there, make sure to git ignore
this file while committing :
APPWRITE_ENDPOINT=http://localhost/v1
APPWRITE_PROJECTID=meili-example
APPWRITE_KEY=find-this-in-project-settings
Note - You will get Appwrite secrets from Settings
in the left pane and you need to generate an API KEY from the API Keys
option on the left.
Creating an Appwrite Function
To create Appwrite function, we use the Appwrite CLI for easy deployment.
- Login to your Appwrite account using the command
appwrite login
- Enter your existing Appwrite project using the command
appwrite init project
and choose the project you want to. - Create a new node.js function or fork our repository and use the command
appwrite deploy function
- Choose the
add-to-meilisearch
function and it will be added to your project
Head on to your Appwrite console and click on Functions
, this is what you will see:
Configuring the Appwrite Function
Now that the function is ready on Appwrite console, to execute it, we need to add some variable.
- Go to
Settings
- Scroll down to
Variables
and fill in data according to the below table:
Key | Value |
---|---|
APPWRITE_FUNCTION_ENDPOINT | http://yourip/v1 |
APPWRITE_FUNCTION_PROJECT_ID | Put in your function id |
APPWRITE_FUNCTION_API_KEY | Put in your API KEY |
APPWRITE_MEILISEARCH_HOST | http://yourip:7700 |
APPWRITE_MEILISEARCH_KEY | Put in the ADMIN API KEY that you get from here |
- Once the above variables are set, your function is ready to run
Building The Search App
To build the frontend of the app we use the following code, in an index.html
file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@meilisearch/instant-meilisearch/templates/basic_search.css" />
</head>
<body>
<div class="wrapper">
<div id="searchbox" focus></div>
<div id="hits"></div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/@meilisearch/instant-meilisearch@0.8.1/dist/instant-meilisearch.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4"></script>
<script>
const search = instantsearch({
indexName: "movie",
searchClient: instantMeiliSearch(
"http://206.189.206.205",
"3ca53aec3885eb48b4d430607dabc5515ea10e4d025319a94eccb6f8d6931823"
)
});
search.addWidgets([
instantsearch.widgets.searchBox({
container: "#searchbox"
}),
instantsearch.widgets.configure({ hitsPerPage: 8 }),
instantsearch.widgets.hits({
container: "#hits",
templates: {
item: `
<div>
<div class="hit-name">
{{#helpers.highlight}}{ "attribute": "title" }{{/helpers.highlight}}
</div>
</div>
`
}
})
]);
search.start();
</script>
</html>
Fetching Data From Appwrite To MeiliSearch
This the final step of the demo, where we bring in all the bits and pieces from above. So far, we have:
- A database up and running in Appwrite - it contains the data that we will use to search the contents
- A meilisearch instance running, ready to search
- A simple frontend UI
- An Appwrite Function running in background which we use to search for movies
In this step, we will trigger the Appwrite function which will fetch data from Appwrite and Meilisearch will use this data to search in our simple application that we built in the above step.
To able able to do that, an additional step will be required in the function:
- Adding
database.create
event, and adding it to your json file, so that every new data added shows up in the search result
Testing the Application
Before testing the application, make sure you have the following things ready:
- Appwrite up and running
- Meilisearch running
- The frontend built using the code in
index.html
- The
dataWrite.js
file ready to upload data to Appwrite - An .env file containing all Appwrite secrets
- Appwrite function ready
Now you need to run the ‘dataWriter.js` file and the Appwrite function running in the background will be pushing the data, which Meilisearch will use to search.
You should see the result on: http://localhost:7700
Ending Notes
If you want to build your own search app, you can find the entire code here
Liked what we built? Here's some resources:
Top comments (0)