轻量级的搜索引擎 Meilisearch
1、安装
cd /opt
mkdir meili_data
docker run -itd -p 7700:7700 -e MEILI_ENV='development' -e MEILI_MASTER_KEY='xxx' -v $(pwd)/meili_data:/meili_data getmeili/meilisearch:v1.0
使用 MASTER_KEY 设定 Meilisearch 的连接密码。
2、引入 Java SDK 依赖
官方提供了主流语言的 SDK,或者使用 HTTP 的方式访问 Meilisearch。我用的是 Java SDK。
<dependency>
<groupId>com.meilisearch.sdk</groupId>
<artifactId>meilisearch-java</artifactId>
<version>0.11.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.10.0</version>
</dependency>
3、建立连接插入数据
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.meilisearch.sdk.Client;
import com.meilisearch.sdk.Config;
import com.meilisearch.sdk.Index;
import com.meilisearch.sdk.exceptions.MeilisearchException;
import com.meilisearch.sdk.model.TaskInfo;
import java.util.ArrayList;
import java.util.List;
public class demo01 {
public static void main(String[] args) throws MeilisearchException {
JSONObject j1 = new JSONObject().put("id", "1").put("title", "Carol").put("genre", new JSONArray("["Romance","Drama"]"));
JSONObject j2 = new JSONObject().put("id", "2").put("title", "Wonder Woman").put("genres",new JSONArray("["Action","Adventure"]"));
JSONObject j3 = new JSONObject().put("id", "3").put("title", "Life of Pi").put("genres",new JSONArray("["Adventure","Drama"]"));
JSONObject j4 = new JSONObject().put("id", "4").put("title", "Mad Max: Fury Road").put("genres",new JSONArray("["Adventure","Science Fiction"]"));
JSONObject j5 = new JSONObject().put("id", "5").put("title", "Moana").put("genres",new JSONArray("["Fantasy","Action"]"));
JSONObject j6 = new JSONObject().put("id", "6").put("title", "Philadelphia").put("genres",new JSONArray("["Drama"]"));
List<JSONObject> jsonObjects = new ArrayList<>();
jsonObjects.add(j1);
jsonObjects.add(j2);
jsonObjects.add(j3);
jsonObjects.add(j4);
jsonObjects.add(j5);
jsonObjects.add(j6);
Client client = new Client(new Config("http://192.168.161.239:7700", "sqlark"));
// An index is where the documents are stored.
Index index = client.index("movies");
// If the index 'movies' does not exist, MeiliSearch creates it when you first add the documents.
for (JSONObject jsonObject : jsonObjects) {
String documents = JSONUtil.toJsonStr(jsonObject);
TaskInfo taskInfo = index.addDocuments(documents,"id");
System.out.println(taskInfo.getStatus());
}
}
}
插入成功如下图所示:
4、搜索
由于其自身搜索会导致 高亮等传入的是 String[] 数组,导致查询时候,转成json 直接取的其hash 值。所以进行了改造。
@Data
@Component("SearchUtil")
@Slf4j
public class SearchUtil {
@Value("${custom.meilisearch.host}")
private String hostUrl;
@Value("${custom.meilisearch.ApiKey}")
private String apiKey;
public SearchResultPaginated searchData(String indexName, SearchRequest searchRequest) {
Client client = new Client(new Config(hostUrl, apiKey));
Index index = null;
try {
index = client.index(indexName);
} catch (Exception e) {
log.error(e.getMessage());
}
JSONObject searchObject = JSONUtil.parseObj(searchRequest);
GsonJsonHandler jsonGson = new GsonJsonHandler();
String requestQuery = "/indexes/" + index.getUid() + "/search";
String url = index.getConfig().getHostUrl() + requestQuery;
HttpRequest httpRequest = HttpUtil.createRequest(Method.POST, url);
httpRequest.header("Authorization", "Bearer "+ index.getConfig().getApiKey());
httpRequest.body(JSONUtil.toJsonStr(searchObject));
HttpResponse httpResponse = httpRequest.execute();
if (isSuccess(httpResponse)) {
JSONObject jsonObject = JSONUtil.parseObj(httpResponse.body());
SearchResultPaginated searchResult = null;
try {
searchResult = jsonGson.decode(JSONUtil.toJsonStr(jsonObject), SearchResultPaginated.class);
} catch (Exception e) {
log.error(e.getMessage());
}
return searchResult;
} else {
throw new RuntimeException("从Meilisearch获取信息失败");
}
}
}