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.
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
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
MeilisearchConfigto provide a
Clientbean:
<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/createIndexto create the index and import data.
After successful import, you can see the index in Meilisearch’s Mini Dashboard and test a keyword search such as "手机".
Call
/meilisearch/updateSettingsto enable filtering by category and sorting by price.
Finally, call
/meilisearch/searchwith parameters to perform keyword search, pagination, category filter, and price ordering.
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
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.