MeiliSearch结果映射Java Bean
文章目录
源头
在家里的homelab上部署了一个MeiliSearch服务,用来替换ElasticSearch。
MeiliSearch的搜索速度确实快,但是在使用过程中,发现它的搜索结果是一个HashMap的列表,而不是Java Bean的列表,而因为MeiliSearch中存储long类型的数据时,会转换为double类型,所以在将HashMap转换为Java Bean时,需要自定义反序列化器,将double转换为long。
解决方案
import com.au92.common.util.json.JsonUtils;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.meilisearch.sdk.model.SearchResult;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* MeiliSearch 结果映射器
*
* @author p_x_c
*/
public class MeiliSearchResultMapper {
private static final ObjectMapper objectMapper = new ObjectMapper();
static {
// 自定义模块,处理 double 到 long 的转换
SimpleModule module = new SimpleModule();
module.addDeserializer(Long.class, new LongDeserializer());
module.addDeserializer(long.class, new LongDeserializer());
objectMapper.registerModule(module);
}
/**
* 自定义 Long 反序列化器,处理 double 到 long 的转换
*/
private static class LongDeserializer extends JsonDeserializer<Long> {
@Override
public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
double doubleValue = p.getDoubleValue();
return Double.valueOf(doubleValue)
.longValue();
}
}
/**
* 通用方法,将 JSON 结果转换为指定类型的 Java Bean 列表
*
* @param searchResult 搜索结果
* @param clazz Java Bean 类型
* @param <T>
* @return
* @throws JsonProcessingException
*/
public static <T> List<T> parseResults(SearchResult searchResult, Class<T> clazz) throws JsonProcessingException {
// 将 searchResult 的 hits 转换为 JSON 数组字符串
ArrayNode hitsArray = (ArrayNode) objectMapper.readTree(JsonUtils.toJSONString(searchResult.getHits()));
List<T> results = new ArrayList<>();
for (JsonNode node : hitsArray) {
T bean = objectMapper.treeToValue(node, clazz);
results.add(bean);
}
return results;
}
/**
* 将单个 HashMap<String, Object> 转换为指定的 Java Bean 类型
*
* @param resultMap
* @param clazz
* @param <T>
* @return
*/
public static <T> T parseResult(Map<String, Object> resultMap, Class<T> clazz) {
return objectMapper.convertValue(resultMap, clazz);
}
}
文章作者 pengxiaochao
上次更新 2024-11-01
许可协议 不允许任何形式转载。