Skip to main content
โšก Calmops

Golang Connect to Meilisearch

Meilisearch is a powerful, open-source search engine that provides fast, typo-tolerant full-text search. Integrating Meilisearch with Golang allows you to build efficient search functionalities in your Go applications. This post provides a step-by-step guide to connecting Go to Meilisearch, preparing data, indexing, and performing searches.

What is Meilisearch?

Meilisearch is a RESTful search API that indexes JSON documents and provides instant search results. It’s designed for ease of use, with features like typo tolerance, filtering, and faceting. It’s written in Rust and can be self-hosted or used via cloud services.

Prerequisites

  • Go 1.16 or later.
  • Meilisearch server running (download from meilisearch.com or use Docker).
  • Meilisearch Go client: go get github.com/meilisearch/meilisearch-go.

Step 1: Setting Up the Project

Create a new Go project and install the Meilisearch client:

mkdir meilisearch-go-example
cd meilisearch-go-example
go mod init meilisearch-go-example
go get github.com/meilisearch/meilisearch-go

Step 2: Connecting to Meilisearch

Initialize the Meilisearch client with your server’s URL and API key (if authentication is enabled).

package main

import (
    "fmt"
    "log"

    "github.com/meilisearch/meilisearch-go"
)

func main() {
    client := meilisearch.New("http://localhost:7700", meilisearch.WithAPIKey("your_master_key"))
    
    // Test connection
    health, err := client.Health()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Meilisearch health:", health.Status)
}

Run Meilisearch locally: meilisearch (default port 7700).

Step 3: Preparing Data

Prepare your data as a slice of structs or maps. Meilisearch works with JSON-like documents.

type Movie struct {
    ID          int      `json:"id"`
    Title       string   `json:"title"`
    Overview    string   `json:"overview"`
    Genres      []string `json:"genres"`
    ReleaseDate string   `json:"release_date"`
}

var movies = []Movie{
    {
        ID:          1,
        Title:       "The Shawshank Redemption",
        Overview:    "Two imprisoned men bond over a number of years...",
        Genres:      []string{"Drama"},
        ReleaseDate: "1994-09-23",
    },
    {
        ID:          2,
        Title:       "The Godfather",
        Overview:    "The aging patriarch of an organized crime dynasty...",
        Genres:      []string{"Crime", "Drama"},
        ReleaseDate: "1972-03-24",
    },
}

Step 4: Creating an Index and Adding Documents

Create an index and populate it with documents.

// Create index
index, err := client.CreateIndex(&meilisearch.IndexConfig{
    Uid:        "movies",
    PrimaryKey: "id",
})
if err != nil {
    log.Fatal(err)
}

// Add documents
task, err := index.AddDocuments(movies)
if err != nil {
    log.Fatal(err)
}
fmt.Println("Task UID:", task.TaskUID)

// Wait for task completion
client.WaitForTask(task.TaskUID)

Step 5: Performing Searches

Search the index with queries.

// Basic search
searchRes, err := index.Search("godfather", &meilisearch.SearchRequest{})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Found %d hits\n", searchRes.EstimatedTotalHits)

// Print results
for _, hit := range searchRes.Hits {
    movie := hit.(map[string]interface{})
    fmt.Printf("Title: %s\n", movie["title"])
}

Step 6: Advanced Features

Filtering

searchRes, err := index.Search("drama", &meilisearch.SearchRequest{
    Filter: "genres = Drama",
})

Faceting

Enable faceting on index creation, then search with facets.

// When creating index, set filterable attributes
index.UpdateFilterableAttributes(&[]string{"genres"})

// Search with facets
searchRes, err := index.Search("", &meilisearch.SearchRequest{
    Facets: []string{"genres"},
})

Updating Documents

updatedMovie := Movie{ID: 1, Title: "Updated Title", ...}
task, err := index.UpdateDocuments([]Movie{updatedMovie})

Deleting Documents

task, err := index.DeleteDocument(1)

Step 7: Handling Errors and Best Practices

  • Always check for errors after API calls.
  • Use WaitForTask for asynchronous operations.
  • Set appropriate timeouts and handle rate limits.
  • Secure your Meilisearch instance with API keys.
  • Monitor performance and use pagination for large result sets.

Conclusion

Connecting Golang to Meilisearch is straightforward with the official client. This setup enables powerful search capabilities in your applications. Experiment with different data types and queries to leverage Meilisearch’s full potential.

For more details, refer to the Meilisearch Go client documentation and Meilisearch docs.

Comments