Backend Development 10 min read

How to Build Fast Product Search with Meilisearch in a SpringBoot Mall Project

This guide walks through integrating Meilisearch into a SpringBoot‑based e‑commerce (mall) project, covering dependency setup, configuration, index creation, data import, searchable API implementation, and a performance comparison with Elasticsearch, all illustrated with code snippets and screenshots.

macrozheng
macrozheng
macrozheng
How to Build Fast Product Search with Meilisearch in a SpringBoot Mall Project

Prerequisite Knowledge

You should be familiar with Meilisearch. If not, refer to introductory tutorials before proceeding.

Mall Project Overview

The Mall project is a SpringBoot3 + Vue e‑commerce system (GitHub stars ~60K) that supports multiple modules, the latest 2024 microservice architecture, Docker, and Kubernetes. It includes front‑end shop and back‑end admin modules covering products, orders, carts, permissions, coupons, members, payments, etc.

GitHub URLs:

Boot project: https://github.com/macrozheng/mall

Cloud project: https://github.com/macrozheng/mall-swarm

Documentation site: https://www.macrozheng.com

Mall project screenshot
Mall project screenshot

Implementing Product Search

Next we will use SpringBoot + Meilisearch to implement product search.

Add Meilisearch Java SDK dependency to

pom.xml

:

<code><!--Meilisearch Java SDK-->
<dependency>
  <groupId>com.meilisearch.sdk</groupId>
  <artifactId>meilisearch-java</artifactId>
  <version>0.14.3</version>
</dependency>
</code>

Add Meilisearch connection configuration to

application.yml

:

<code>meilisearch:
  host: http://192.168.3.101:7700
  index: products
</code>

Create a Java configuration class

MeilisearchConfig

to provide a

Client

bean:

<code>@Configuration
public class MeilisearchConfig {
    @Value("${meilisearch.host}")
    private String MEILISEARCH_HOST;

    @Bean
    public Client searchClient() {
        return new Client(new Config(MEILISEARCH_HOST, null));
    }
}
</code>

Create a controller to manage the index, import data, and expose search APIs:

<code>@RestController
@RequestMapping("/meilisearch")
public class MeilisearchController {
    @Value("${meilisearch.index}")
    private String MEILISEARCH_INDEX;

    @Autowired
    private Client searchClient;

    @Operation(summary = "Create index and import product data")
    @GetMapping("/createIndex")
    public CommonResult createIndex() {
        ClassPathResource resource = new ClassPathResource("json/products.json");
        String jsonStr = IoUtil.read(resource.getStream(), Charset.forName("UTF-8"));
        Index index = searchClient.index(MEILISEARCH_INDEX);
        TaskInfo info = index.addDocuments(jsonStr, "id");
        return CommonResult.success(info);
    }

    @Operation(summary = "Delete product index")
    @GetMapping("/deleteIndex")
    public CommonResult deleteIndex() {
        TaskInfo info = searchClient.deleteIndex(MEILISEARCH_INDEX);
        return CommonResult.success(info);
    }

    @Operation(summary = "Get index settings")
    @GetMapping("/getSettings")
    public CommonResult getSettings() {
        Settings settings = searchClient.index(MEILISEARCH_INDEX).getSettings();
        return CommonResult.success(settings);
    }

    @Operation(summary = "Update index settings for filtering and sorting")
    @GetMapping("/updateSettings")
    public CommonResult updateSettings() {
        Settings settings = new Settings();
        settings.setFilterableAttributes(new String[]{"productCategoryName"});
        settings.setSortableAttributes(new String[]{"price"});
        TaskInfo info = searchClient.index(MEILISEARCH_INDEX).updateSettings(settings);
        return CommonResult.success(info);
    }

    @Operation(summary = "Search products with keyword, pagination, category filter, and price order")
    @GetMapping("/search")
    @ResponseBody
    public CommonResult search(@RequestParam(required = false) String keyword,
                               @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                               @RequestParam(required = false, defaultValue = "5") Integer pageSize,
                               @RequestParam(required = false) String productCategoryName,
                               @RequestParam(required = false, value = "0->asc;1->desc") Integer order) {
        SearchRequest.SearchRequestBuilder searchBuilder = SearchRequest.builder();
        searchBuilder.page(pageNum);
        searchBuilder.hitsPerPage(pageSize);
        if (StrUtil.isNotEmpty(keyword)) {
            searchBuilder.q(keyword);
        }
        if (StrUtil.isNotEmpty(productCategoryName)) {
            searchBuilder.filter(new String[]{"productCategoryName=" + productCategoryName});
        }
        if (order != null) {
            if (order == 0) {
                searchBuilder.sort(new String[]{"price:asc"});
            } else if (order == 1) {
                searchBuilder.sort(new String[]{"price:desc"});
            }
        }
        Searchable searchable = searchClient.index(MEILISEARCH_INDEX).search(searchBuilder.build());
        return CommonResult.success(searchable);
    }
}
</code>

Sample product JSON (excerpt):

<code>{
  "id": 27,
  "productSn": "7437788",
  "brandId": 6,
  "brandName": "小米",
  "productCategoryId": 19,
  "productCategoryName": "手机通讯",
  "pic": "http://macro-oss.oss-cn-shenzhen.aliyuncs.com/mall/images/20180615/xiaomi.jpg",
  "name": "小米8 全面屏游戏智能手机 6GB+64GB 黑色 全网通4G 双卡双待",
  "subTitle": "骁龙845处理器,红外人脸解锁,AI变焦双摄,AI语音助手小米6X低至1299,点击抢购",
  "price": 2699.0,
  "sale": 99,
  "newStatus": 1,
  "recommandStatus": 1,
  "stock": 100,
  "promotionType": 3,
  "sort": 0
}
</code>

Feature Demonstration

Start both the Mall project and the Meilisearch service, then use the automatically generated Swagger UI (http://localhost:8080/swagger-ui/index.html) to test the APIs.

Call

/meilisearch/createIndex

to create the index and import data.

Create index screenshot
Create index screenshot

After successful import, you can see the index in Meilisearch’s Mini Dashboard and test a keyword search such as "手机".

Search result screenshot
Search result screenshot

Call

/meilisearch/updateSettings

to enable filtering by category and sorting by price.

Update settings screenshot
Update settings screenshot

Finally, call

/meilisearch/search

with parameters to perform keyword search, pagination, category filter, and price ordering.

Search API screenshot
Search API screenshot

Comparison Between Meilisearch and Elasticsearch

Architecture & Design: Meilisearch is lightweight and ready‑to‑use; Elasticsearch is distributed and requires complex deployment.

Performance: Meilisearch delivers sub‑50 ms response for small‑to‑medium datasets; Elasticsearch excels with large‑scale data.

SDK: Meilisearch offers simple, multi‑language APIs; Elasticsearch has a rich plugin ecosystem but higher learning curve.

Chinese Support: Meilisearch natively supports Chinese; Elasticsearch needs additional Chinese tokenizers.

Resource Consumption: Meilisearch has low memory footprint; Elasticsearch consumes more memory.

Conclusion

We have demonstrated how to implement product search using Meilisearch, which natively supports Chinese and provides a concise API, making it a convenient choice for fast search functionality.

Source Code

GitHub repository: https://github.com/macrozheng/spring-examples/tree/master/spring-meilisearch

Javabackend developmentSpringBootProduct SearchMeilisearch
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.