© 2023-2024 The original author(s).

Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.

Preface

2. Requirements

Requires an installation of Meilisearch.

Reference Documentation

3. Meilisearch Client

This chapter describes configuration and usage of the Meilisearch client.

Spring Data Meilisearch operates upon a Meilisearch Client (provided by Meilisearch Java) that is connected to a single Meilisearch instance.

3.1. Annotation based configuration

The Spring Data Meilisearch client can be configured using the @Configuration annotation.

Example 1. Spring Data Meilisearch client using JavaConfig
import io.vanslog.spring.data.meilisearch.client.ClientConfiguration;
import io.vanslog.spring.data.meilisearch.config.MeilisearchConfiguration;

import org.springframework.context.annotation.Configuration;

@Configuration
public class MyClientConfig extends MeilisearchConfiguration {

    @Override
    public ClientConfiguration clientConfiguration() {
        return ClientConfiguration.builder()           (1)
                .connectedToLocalhost()
                .withApiKey("masterKey")
                .build();
    }
}
1 for a detailed description of the builder methods see Client Configuration

3.2. Spring Namespace

The Spring Data Meilisearch client can be configured using the Spring XML namespace.

Example 2. Spring Data Meilisearch client using XML Namespace
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:meilisearch="http://www.vanslog.io/spring/data/meilisearch"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.vanslog.io/spring/data/meilisearch
       http://www.vanslog.io/spring/data/meilisearch/spring-meilisearch-1.0.xsd">

    <meilisearch:meilisearch-client id="meilisearchClient" api-key="masterKey"/>

</beans>
When setting up a client using the Spring namespace, a JSON handler must be set up. Use the following section, Spring Namespace of JSON handler.

3.3. Client Configuration

Configuration options are provided by the ClientConfiguration builder.

Example 3. Client Configuration
String[] agents = {"Spring Data Meilisearch"};                          (1)

ClientConfiguration clientConfiguration = ClientConfiguration.builder()
    .connectedTo("http://localhost:7700")                               (2)
    .withApiKey("masterKey")                                            (3)
    .withClientAgents(agents)                                           (4)
    .withRequestTimeout(2000)                                           (5)
    .withRequestInterval(20)                                            (6)
    .build();
1 Define the client agents that will be sent as a User-Agent header to Meilisearch.
2 Use the builder to provide the Meilisearch host URL.
3 Set the Meilisearch API Key to use for authentication.
4 Set the client agents.
5 Set the request timeout to 2000 milliseconds.
6 Set the request interval to 20 milliseconds.

3.4. JSON handler

The JSON handler is used to serialize and deserialize the JSON data.

3.4.1. Supported JSON handlers

The following JSON handlers are supported:

  • com.meilisearch.sdk.json.GsonJsonhandler

  • com.meilisearch.sdk.json.JacksonJsonhandler

  • Custom JSON handler that implements com.meilisearch.sdk.json.Jsonhandler

3.4.2. Annotation based configuration

You don’t need to provide a JSON handler if you are using the default JSON handler, GsonJsonhandler. But you can override the jsonhandler() method to provide a custom JSON handler.

Example 4. Setting JSON handler using JavaConfig
import io.vanslog.spring.data.meilisearch.config.MeilisearchConfiguration;

import org.springframework.context.annotation.Configuration;

@Configuration
public class JsonhandlerConfig extends MeilisearchConfiguration {

    @Override
    public Jsonhandler jsonhandler() {
        return new JacksonJsonhandler();    (1)
    }
}
1 Use Jackson JSON handler instead of the default JSON handler.

3.4.3. Spring Namespace

The JSON handler must be registered as a bean with the id=jsonhandler. And pass the class name of the JSON handler to the class attribute.

Example 5. Setting JSON handler using XML Namespace
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:meilisearch="http://www.vanslog.io/spring/data/meilisearch"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.vanslog.io/spring/data/meilisearch
       http://www.vanslog.io/spring/data/meilisearch/spring-meilisearch-1.0.xsd">

    <bean id="jsonhandler" class="com.meilisearch.sdk.json.GsonJsonhandler"/>

</beans>

4. Meilisearch Document

Spring Data Meilisearch provides a simple way to define a Document.

4.1. Document definition

To define the Document, you need to annotate a class with @Document annotation. As an example, the following class defines a Movie document with id, title, description and genres fields.

Example 6. The sample document
import io.vanslog.spring.data.meilisearch.annotations.Document;

import org.springframework.data.annotation.Id;

@Document(indexUid = "movies")
public class Movie {
    @Id private int id;
    private String title;
    private String description;
    private String[] genres;
}

4.2. Index UID

The Index UID is a unique identifier for an index. It must be defined for each document with @Document annotation.

4.3. Document id

The Document id is a unique identifier for a document in an index. It can be defined with @Id annotation or id field.

5. Meilisearch Repositories

This chapter describes how to use Meilisearch repositories.

5.1. Usage

Meilisearch repositories are used to store and retrieve data from Meilisearch.

Example 7. The sample repository
import io.vanslog.spring.data.meilisearch.repository.MeilisearchRepository;

import java.util.List;

public class MovieService {

	private final MovieRepository repository;

	public MovieService(MovieRepository repository) {
		this.repository = repository;
	}

	public List<Movie> showAllMovies() {
		return repository.findAll();
	}
}

public interface MovieRepository extends MeilisearchRepository<Movie, String> {

}

5.2. Automatic creation of indexes with the corresponding mapping

If the @Document annotation is present on the entity, the index will be created automatically with the corresponding mapping.

5.3. Lookup methods

The Meilisearch repository provides the following lookup methods:

  • findById(String id)

  • findAllById(Iterable<String> ids)

  • findAll()

  • findAll(Sort sort)

  • findAll(Pageable pageable)

Note that the above methods perform different behaviors. The findById and findAllById methods use the Get one document or Get documents API. However, the findAll method uses the Search API.

This difference in behavior can also cause results to show differently. For example, displayedAttributes in Meilisearch Settings does not work with the Get one document or Get documents API. Go to Meilisearch documentation for more information.

5.4. Annotation based configuration

The Spring Data Meilisearch repositories can be configured using the @EnableMeilisearchRepositories annotation.

Example 8. Spring Data Meilisearch repositories using JavaConfig
import io.vanslog.spring.data.meilisearch.core.MeilisearchOperations;
import io.vanslog.spring.data.meilisearch.repository.config.EnableMeilisearchRepositories;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableMeilisearchRepositories(                             (1)
		basePackages = {"com.example.repositories"}
)
public class Config {

    @Bean
    public MeilisearchOperations meilisearchTemplate() {    (2)
        // ...
    }
}
1 The @EnableMeilisearchRepositories annotation enables Meilisearch repositories. If no basePackages are configured, the annotation will scan the package of the annotated configuration class.
2 Provide a MeilisearchOperations bean to override the default MeilisearchTemplate bean.

5.5. Spring Namespace

The Spring Data Meilisearch repositories can be configured using the meilisearch namespace.

Example 9. Spring Data Meilisearch repositories using Namespace
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:meilisearch="http://www.vanslog.io/spring/data/meilisearch"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.vanslog.io/spring/data/meilisearch
       http://www.vanslog.io/spring/data/meilisearch/spring-meilisearch-1.0.xsd">

    <meilisearch:repositories base-package="com.example.repositories"/>             (1)

    <bean name="meilisearchTemplate"                                                (2)
          class="io.vanslog.spring.data.meilisearch.core.MeilisearchTemplate">
        <constructor-arg name="meilisearchClient" ref="meilisearchClient"/>         (3)
    </bean>

    <meilisearch:meilisearch-client id="meilisearchClient" api-key="masterKey"/>    (4)
    <bean id="jsonHandler" class="com.meilisearch.sdk.json.GsonJsonHandler"/>       (5)
</beans>
1 The meilisearch:repositories element enables Meilisearch repositories. If no base-package is configured, the namespace will scan the package of the configuration file.
2 The meilisearchTemplate bean must be configured with a MeilisearchClient.
3 Set the client bean as the constructor argument of the meilisearchTemplate.
4 Configure the Meilisearch client with the api-key attribute.
5 Configure the jsonHandler bean with the GsonJsonHandler class.

6. Meilisearch Settings

This chapter covers how to modify search settings in Meilisearch.

6.1. Overview

Meilisearch settings are used to define the behavior of the search engine. Using @Setting annotation, you can define the settings for the index.

@Document(indexUid = "products")
@Setting(
  sortAttributes = { "productId" },                                                  (1)
  distinctAttribute = "productId",                                                   (2)
  searchableAttributes = { "description", "brand", "color" },                        (3)
  displayedAttributes = { "description", "brand", "color", "productId" },            (4)
  rankingRules = { "typo", "words", "proximity", "attribute", "sort", "exactness" }, (5)
  stopWords = { "a", "an", "the" },                                                  (6)
)
class Product {
    @Id private String id;
    private String description;
    private String brand;
    private String color;
    private String productId;
}
1 The sortAttributes attribute is used to define the fields that must be used for sorting the results.
2 The distinctAttribute attribute is used to define the field that must be used to remove duplicates from the results.
3 The searchableAttributes attribute is used to define the fields that must be used for searching the results.
4 The displayedAttributes attribute is used to define the fields that must be displayed in the results.
5 The rankingRules attribute is used to define the ranking rules that must be used for sorting the results.
6 The stopWords attribute is used to define the stop words that must be used for searching the results.

6.2. Pagination

Meilisearch’s search function is limited to return a maximum of 1,000 results. Therefore, search(SearchRequest searchRequest, Class<?> clazz) in MeilisearchOperation can’t return more than 1,000 results.

If you have more than 1,000 results, you must use @Pagination annotation to extract the remaining results.

@Document(indexUid = "products")
@Setting(
  pagination = @Pagination(maxTotalHits = 2000)                                       (1)
)
class Product {
    @Id private String id;
    private String description;
    private String brand;
    private String color;
    private String productId;
}
1 The maxTotalHits is used to define the maximum number of results that must be returned by the search engine.