中国建设银行网站能解密码,深圳如何搭建制作网站,小米路由器3做网站,做网站需要租服务器么一、Meilisearch与Easy Search点击进入官网了解#xff0c;本文主要从小微型公司业务出发#xff0c;选择meilisearch来作为项目的全文搜索引擎#xff0c;还可以当成来mongodb来使用。
二、starter封装
1、项目结构展示 2、引入依赖包 dependenciesdependenc…一、Meilisearch与Easy Search点击进入官网了解本文主要从小微型公司业务出发选择meilisearch来作为项目的全文搜索引擎还可以当成来mongodb来使用。
二、starter封装
1、项目结构展示 2、引入依赖包 dependenciesdependencygroupIdcn.iocoder.boot/groupIdartifactIdyudao-common/artifactId/dependency!-- meilisearch 轻量级搜索 --!-- https://mvnrepository.com/artifact/com.meilisearch.sdk/meilisearch-java --dependencygroupIdcom.meilisearch.sdk/groupIdartifactIdmeilisearch-java/artifactIdversion0.11.2/version/dependency!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 --dependencygroupIdcom.alibaba.fastjson2/groupIdartifactIdfastjson2/artifactIdversion2.0.40/versionscopeprovided/scope/dependency!-- Web 相关 --dependencygroupIdcn.iocoder.boot/groupIdartifactIdyudao-spring-boot-starter-web/artifactIdscopeprovided/scope !-- 设置为 provided只有 OncePerRequestFilter 使用到 --/dependency/dependencies
3、yml参数读取代码参考
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;/*** MeiliSearch 自动装配参数类* 2023年9月21日*/
ConfigurationProperties(yudao.meilisearch)
Data
Validated
public class MeiliSearchProperties {/*** 主机地址*/private String hostUrl ;/*** 接口访问标识*/private String apiKey 123456;}
4、自动配置类代码参考
import com.meilisearch.sdk.Client;
import com.meilisearch.sdk.Config;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;import javax.annotation.Resource;/*** MeiliSearch 自动装配类* 2023年9月21日*/
AutoConfiguration
EnableConfigurationProperties({MeiliSearchProperties.class})
EnableCaching
public class MeiliSearchAutoConfiguration {ResourceMeiliSearchProperties properties;BeanConditionalOnMissingBean(Client.class)Client client() {return new Client(config());}BeanConditionalOnMissingBean(Config.class)Config config() {return new Config(properties.getHostUrl(), properties.getApiKey());}}
5、数据处理类参考
import com.meilisearch.sdk.json.GsonJsonHandler;import java.util.List;/*** MeiliSearch json解析类* 2023年9月21日*/
public class JsonHandler {private com.meilisearch.sdk.json.JsonHandler jsonHandler new GsonJsonHandler();public T SearchResultT resultDecode(String o, ClassT clazz) {Object result null;try {result jsonHandler.decode(o, SearchResult.class, clazz);} catch (Exception e) {e.printStackTrace();}return result null ? null : (SearchResultT) result;}public T ListT listDecode(Object o, ClassT clazz) {Object list null;try {list jsonHandler.decode(o, List.class, clazz);} catch (Exception e) {e.printStackTrace();}return list null ? null : (ListT) list;}public String encode(Object o) {try {return jsonHandler.encode(o);} catch (Exception e) {e.printStackTrace();return null;}}public T T decode(Object o, ClassT clazz) {T t null;try {t jsonHandler.decode(o, clazz);} catch (Exception e) {e.printStackTrace();}return t;}
}import java.util.List;
import java.util.Map;/*** MeiliSearch* 2023年9月21日*/
public class MatchedBeanT {private T _formatted;private MapString, ListMatching _matchesInfo;public T get_formatted() {return _formatted;}public void set_formatted(T _formatted) {this._formatted _formatted;}public MapString, ListMatching get_matchesInfo() {return _matchesInfo;}public void set_matchesInfo(MapString, ListMatching _matchesInfo) {this._matchesInfo _matchesInfo;}private class Matching {long start;long length;public long getStart() {return start;}public void setStart(long start) {this.start start;}public long getLength() {return length;}public void setLength(long length) {this.length length;}}
}import java.util.List;/*** MeiliSearch* 2023年9月21日*/
public class SearchResultT {private String query;private long offset;private long limit;private long processingTimeMs;private long nbHits;private boolean exhaustiveNbHits;private ListT hits;public String getQuery() {return query;}public void setQuery(String query) {this.query query;}public long getOffset() {return offset;}public void setOffset(long offset) {this.offset offset;}public long getLimit() {return limit;}public void setLimit(long limit) {this.limit limit;}public long getProcessingTimeMs() {return processingTimeMs;}public void setProcessingTimeMs(long processingTimeMs) {this.processingTimeMs processingTimeMs;}public long getNbHits() {return nbHits;}public void setNbHits(long nbHits) {this.nbHits nbHits;}public boolean isExhaustiveNbHits() {return exhaustiveNbHits;}public void setExhaustiveNbHits(boolean exhaustiveNbHits) {this.exhaustiveNbHits exhaustiveNbHits;}public ListT getHits() {return hits;}public void setHits(ListT hits) {this.hits hits;}Overridepublic String toString() {return SearchResult{ query query \ , offset offset , limit limit , processingTimeMs processingTimeMs , nbHits nbHits , exhaustiveNbHits exhaustiveNbHits , hits hits };}
}
6、自定义注解代码参考
import java.lang.annotation.*;/*** MeiliSearch* 2023年9月21日*/
Documented
Target(ElementType.FIELD)
Retention(RetentionPolicy.RUNTIME)
public interface MSFiled {/*** 是否开启过滤*/boolean openFilter() default false;/*** 是否不展示*/boolean noDisplayed() default false;/*** 是否开启排序*/boolean openSort() default false;/*** 处理的字段名*/String key() ;
}import java.lang.annotation.*;/*** MeiliSearch* 2023年9月21日*/
Documented
Target(ElementType.TYPE)
Retention(RetentionPolicy.RUNTIME)
public interface MSIndex {/*** 索引*/String uid() default ;/*** 主键*/String primaryKey() default ;/*** 分类最大数量*/int maxValuesPerFacet() default 100;/*** 单次查询最大数量*/int maxTotalHits() default 1000;
}
7、基础操作接口封装
import cn.iocoder.yudao.framework.meilisearch.json.SearchResult;
import com.meilisearch.sdk.SearchRequest;
import com.meilisearch.sdk.model.Settings;
import com.meilisearch.sdk.model.Task;
import com.meilisearch.sdk.model.TaskInfo;import java.util.List;/*** MeiliSearch 基础接口* 2023年9月21日*/
interface DocumentOperationsT {T get(String identifier);ListT list();ListT list(int limit);ListT list(int offset, int limit);long add(T document);long update(T document);long add(ListT documents);long update(ListT documents);long delete(String identifier);long deleteBatch(String... documentsIdentifiers);long deleteAll();SearchResultT search(String q);SearchResultT search(String q, int offset, int limit);SearchResultT search(SearchRequest sr);Settings getSettings();TaskInfo updateSettings(Settings settings);TaskInfo resetSettings();Task getUpdate(int updateId);
}
8、基本操作实现
import cn.iocoder.yudao.framework.meilisearch.json.JsonHandler;
import cn.iocoder.yudao.framework.meilisearch.json.MSFiled;
import cn.iocoder.yudao.framework.meilisearch.json.MSIndex;
import cn.iocoder.yudao.framework.meilisearch.json.SearchResult;
import com.alibaba.fastjson2.JSON;
import com.meilisearch.sdk.*;
import com.meilisearch.sdk.model.*;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.StringUtils;import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.*;/*** MeiliSearch 基本操作实现* 2023年9月21日*/
public class MeilisearchRepositoryT implements InitializingBean, DocumentOperationsT {private Index index;private ClassT tClass;private JsonHandler jsonHandler new JsonHandler();Resourceprivate Client client;Overridepublic T get(String identifier) {T document;try {document index.getDocument(identifier, tClass);} catch (Exception e) {throw new RuntimeException(e);}return document;}Overridepublic ListT list() {ListT documents;try {documents Optional.ofNullable(index.getDocuments(tClass)).map(indexDocument - indexDocument.getResults()).map(result - Arrays.asList(result)).orElse(new ArrayList());} catch (Exception e) {throw new RuntimeException(e);}return documents;}Overridepublic ListT list(int limit) {ListT documents;try {DocumentsQuery query new DocumentsQuery();query.setLimit(limit);documents Optional.ofNullable(index.getDocuments(query, tClass)).map(indexDocument - indexDocument.getResults()).map(result - Arrays.asList(result)).orElse(new ArrayList());} catch (Exception e) {throw new RuntimeException(e);}return documents;}Overridepublic ListT list(int offset, int limit) {ListT documents;try {DocumentsQuery query new DocumentsQuery();query.setLimit(limit);query.setOffset(offset);documents Optional.ofNullable(index.getDocuments(query, tClass)).map(indexDocument - indexDocument.getResults()).map(result - Arrays.asList(result)).orElse(new ArrayList());} catch (Exception e) {throw new RuntimeException(e);}return documents;}Overridepublic long add(T document) {ListT list Collections.singletonList(document);return add(list);}Overridepublic long update(T document) {ListT list Collections.singletonList(document);return update(list);}Overridepublic long add(List documents) {int taskId;try {taskId index.addDocuments(JSON.toJSONString(documents)).getTaskUid();} catch (Exception e) {throw new RuntimeException(e);}return taskId;}Overridepublic long update(List documents) {int updates;try {updates index.updateDocuments(JSON.toJSONString(documents)).getTaskUid();} catch (Exception e) {throw new RuntimeException(e);}return updates;}Overridepublic long delete(String identifier) {int taskId;try {taskId index.deleteDocument(identifier).getTaskUid();} catch (Exception e) {throw new RuntimeException(e);}return taskId;}Overridepublic long deleteBatch(String... documentsIdentifiers) {int taskId;try {taskId index.deleteDocuments(Arrays.asList(documentsIdentifiers)).getTaskUid();} catch (Exception e) {throw new RuntimeException(e);}return taskId;}Overridepublic long deleteAll() {int taskId;try {taskId index.deleteAllDocuments().getTaskUid();} catch (Exception e) {throw new RuntimeException(e);}return taskId;}Overridepublic cn.iocoder.yudao.framework.meilisearch.json.SearchResultT search(String q) {String result;try {result JSON.toJSONString(index.search(q));} catch (Exception e) {throw new RuntimeException(e);}return jsonHandler.resultDecode(result, tClass);}Overridepublic cn.iocoder.yudao.framework.meilisearch.json.SearchResultT search(String q, int offset, int limit) {SearchRequest searchRequest SearchRequest.builder().q(q).offset(offset).limit(limit).build();return search(searchRequest);}Overridepublic SearchResultT search(SearchRequest sr) {String result;try {result JSON.toJSONString(index.search(sr));} catch (Exception e) {throw new RuntimeException(e);}return jsonHandler.resultDecode(result, tClass);}Overridepublic Settings getSettings() {try {return index.getSettings();} catch (Exception e) {throw new RuntimeException(e);}}Overridepublic TaskInfo updateSettings(Settings settings) {try {return index.updateSettings(settings);} catch (Exception e) {throw new RuntimeException(e);}}Overridepublic TaskInfo resetSettings() {try {return index.resetSettings();} catch (Exception e) {throw new RuntimeException(e);}}Overridepublic Task getUpdate(int updateId) {try {return index.getTask(updateId);} catch (Exception e) {throw new RuntimeException(e);}}Overridepublic void afterPropertiesSet() throws Exception {initIndex();}public Index getIndex() {return index;}/*** 初始化索引信息** throws Exception*/private void initIndex() throws Exception {Class? extends MeilisearchRepository clazz getClass();tClass (ClassT) ((ParameterizedType) clazz.getGenericSuperclass()).getActualTypeArguments()[0];MSIndex annoIndex tClass.getAnnotation(MSIndex.class);String uid annoIndex.uid();String primaryKey annoIndex.primaryKey();if (StringUtils.isEmpty(uid)) {uid tClass.getSimpleName().toLowerCase();}if (StringUtils.isEmpty(primaryKey)) {primaryKey id;}int maxTotalHit1000;int maxValuesPerFacet100;if (Objects.nonNull(annoIndex.maxTotalHits())){maxTotalHitannoIndex.maxTotalHits();}if (Objects.nonNull(annoIndex.maxValuesPerFacet())){maxValuesPerFacet100;}ListString filterKey new ArrayList();ListString sortKey new ArrayList();ListString noDisPlay new ArrayList();//获取类所有属性for (Field field : tClass.getDeclaredFields()) {//判断是否存在这个注解if (field.isAnnotationPresent(MSFiled.class)) {MSFiled annotation field.getAnnotation(MSFiled.class);if (annotation.openFilter()) {filterKey.add(annotation.key());}if (annotation.openSort()) {sortKey.add(annotation.key());}if (annotation.noDisplayed()) {noDisPlay.add(annotation.key());}}}ResultsIndex indexes client.getIndexes();Index[] results indexes.getResults();Boolean isHaveIndexfalse;for (Index result : results) {if (uid.equals(result.getUid())){isHaveIndextrue;break;}}if (isHaveIndex){client.updateIndex(uid,primaryKey);this.index client.getIndex(uid);Settings settings new Settings();settings.setDisplayedAttributes(noDisPlay.size()0?noDisPlay.toArray(new String[noDisPlay.size()]):new String[]{*});settings.setFilterableAttributes(filterKey.toArray(new String[filterKey.size()]));settings.setSortableAttributes(sortKey.toArray(new String[sortKey.size()]));index.updateSettings(settings);}else {client.createIndex(uid, primaryKey);}}
}9、指定自动配置类所在 10、项目有统一版本管理的设置下版本管理 二、项目引用
1、引入starter依赖没有版本统一管理的要把version加上 2、基本使用
2.1、建立索引(宽表)
import cn.iocoder.yudao.framework.meilisearch.json.MSFiled;
import cn.iocoder.yudao.framework.meilisearch.json.MSIndex;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;Data
Builder
AllArgsConstructor
NoArgsConstructor
MSIndex(uid com_baidu_main, primaryKey id)
public class MainDO {private Long id;private String seedsName;MSFiled(openFilter true, key isDelete)private Integer isDelete;MSFiled(openFilter true, key status)private Integer status;MSFiled(openFilter true, key classFiledId)private Integer classFiledId;private String classFiledName;MSFiled(openFilter true, key tags)private ListTageInfo tags;
}
2.2、集成starter里边的mapper对milisearch进行基本操作
import cn.iocoder.yudao.framework.meilisearch.core.MeilisearchRepository;
import org.springframework.stereotype.Repository;Repository
public class MeiliSearchMapper extends MeilisearchRepositoryMainDO {
}
2.3、基本使用
Resource
private MeiliSearchMapper meiliSearchMapper;//根据标签分页查询
SearchRequest searchRequest4 SearchRequest.builder().limit(pageParam.getPageSize().intValue()).sort(new String[]{createTime:desc}).offset(pageParam.getPageNo().intValue() 0 ? pageParam.getPageNo().intValue() : (pageParam.getPageNo().intValue() - 1) * pageParam.getPageSize().intValue()).filter(new String[]{tags.id 10010 AND status1 AND isDelete0}).build();
SearchResultMainDO search4 meiliSearchMapper.search(searchRequest4);//保存Or编辑
ListSeedsDO articleCardDTOS new ArrayList();
Boolean aBoolean meiliSearchMapper.add(articleCardDTOS) 0 ? Boolean.TRUE : Boolean.FALSE;
//按id删除
meiliSearchMapper.delete(String.valueOf(10085));//根据类目分页查询
SearchRequest searchRequest3 SearchRequest.builder().limit(pageParam.getPageSize().intValue()).offset(pageParam.getPageNo().intValue() 0 ? pageParam.getPageNo().intValue() : (pageParam.getPageNo().intValue() - 1) * pageParam.getPageSize().intValue()).build();
StringBuffer sb1 new StringBuffer();
sb.append(status 1 AND isDelete0).append( AND ).append(categoryId ).append(10086L);
searchRequest.setFilter(new String[]{sb.toString()});
searchRequest.setSort(new String[]{createTime:desc});
SearchResultSeedsDO search3 meiliSearchMapper.search(searchRequest3);