搜索综合/视频需求实现点:
1、搜索关键词:动态内容模糊匹配 或 动态内容标签名称模糊匹配 或 动态关联话题名称模糊匹配
2、数据状态:启用 & 未删除 & 动态展示场景1展示在圈子
3、排序:浏览量 > 点赞量 > 发布时间倒序
为实现当前搜索需求,设计数据对象:
/**
* @Author: FJT
* @Date: 2024/1/16 10:27 AM
*/
@Data
public class SaveSolrReq {
/**话题id**/
private Long topicId;
/**话题名称**/
private String topicName;
/**话题描述**/
private String topicDesc;
/**话题封面图url**/
private String topicCover;
/**话题来源 1:官方,2:个人**/
private String topicSource;
/**是否是推荐话题:1:是 0:否**/
private Integer topicRecommend;
/**话题浏览量**/
private Long topicPageView;
/**话题创建时间**/
private Date topicCreateDateTime;
/**话题活动id**/
private Long activityId;
/**话题分类id**/
private List<Long> topicCategoryId;
/**话题分类名称**/
private List<String> topicCategoryName;
/**动态id**/
private Long id;
/**动态内容**/
private String momentsContent;
/**动态video类型 1:图片 2:视频**/
private Integer videoType;
/**动态点赞量**/
private Long momentsLikeNum;
/**动态浏览量**/
private Long momentsViewNum;
/**动态评论量**/
private Long momentsReviewNum;
/**动态收藏量**/
private Long momentsCollectNum;
/**video地址**/
private List<String> videoUrls;
/**图片尺寸 长(px)**/
private Integer videoLongPx;
/**图片尺寸 宽(px)**/
private Integer videoWidePx;
/**动态创建人用户id**/
private Long momentsUserId;
/**动态创建人用户昵称**/
private String momentsUserName;
/**动态创建人用户头像**/
private String momentsUserAvatar;
/**动态分类id**/
private List<Long> momentsCategoryId;
/**动态分类名称**/
private List<String> momentsCategoryName;
/**是否是推荐动态 1:是,0:否**/
private Integer momentsRecommend;
/**是否开启永久置顶 1:是 0:否***/
private Integer foreverTop;
/**发布动态位置**/
private String location;
/**发布动态经度**/
private String longitude;
/**发布动态纬度**/
private String latitude;
/**动态发布时间**/
private Date momentsCreateDateTime;
/**动态商品id**/
private List<Long> momentsProductId;
/**动态社群id**/
private List<Long> momentsCommunityIds;
/**动态展示场景 1:展示在圈子,2:宠物详情开箱精选,3:用品订单开箱精选,4:展示在关注,搜索场景查询1**/
private Integer momentsShowType;
/**圈子id 默认为0**/
private Long communityId;
/**是否是官方用户 1:是 0:否**/
private Integer officialUser;
/**是否删除 1:是 0:否**/
private Integer deleted;
/**
* 是否启用:1-启用,0-禁用
*/
private Integer enabled;
/**记录更新时间,系统使用,不用传递**/
private Date updateDateTime;
}
solr中的schema配置文件,调整字段类型,一般在managed-schema中
注意改完需要重启solr,如果是docker安装的solr的话,直接运行
# 重启solr
docker restart solr
插入数据验证:
@Override
public Result saveSolrData(List<SaveSolrReq> reqs) {
try {
long l1 = System.currentTimeMillis();
for (int i = 0; i < reqs.size(); i++) {
log.info("solr保存数据入参:{}",JSONUtil.toJsonStr(reqs.get(i)));
reqs.get(i).setUpdateDateTime(new Date());
SolrInputDocument inputDocument = new SolrInputDocument();
Map<String, Object> map = BeanUtil.beanToMap(reqs.get(i));
if (CollectionUtil.isNotEmpty(map)) {
map.forEach((k, v) -> {
inputDocument.addField(k, v);
});
}
solrClient.add(inputDocument);
if ((i + 1) % 1000 == 0 || i == reqs.size() - 1) {
log.info("开始提交");
solrClient.commit();
}
}
long l2 = System.currentTimeMillis();
log.info("数据插入耗时:{}",(l2-l1));
return Result.success();
} catch (SolrServerException e) {
log.error("solr数据添加失败:{}", e);
throw new BusinessException("solr数据添加失败");
} catch (IOException e) {
log.error("solr数据添加失败:{}", e);
throw new BusinessException("solr数据添加失败");
}
}
造50w测试数据:
编写数据查询代码,模糊查询匹配:关键字前后拼*,and条件通过增加fq设置,排序可以根据加入的顺序来控制
public Result<CommunitySearchVo> searchKey(CommunitySearchParam param) {
//2.创建查询语句
String keyWord="*"+param.getSearchWord()+"*";
SolrQuery query = new SolrQuery("momentsContent:"+keyWord+" or momentsCategoryName:"+keyWord+
" or topicName:"+keyWord);
query.add("fq", "momentsShowType:" + MomentsShowTypeEnum.TYPE_1.getType());
query.add("fq", "deleted:0");
query.add("fq", "enabled:1");
//增加视频过滤条件
if (Objects.equals(SearchType.TYPE_2.getType(), param.getSearchType())) {
query.add("fq", "videoType:"+ SearchType.TYPE_2.getType());
}
query.setStart((param.getPage_number() - 1) * param.getPage_size());
query.setRows(param.getPage_size());
query.addSort("officialUser", SolrQuery.ORDER.desc);
query.addSort("foreverTop", SolrQuery.ORDER.desc);
query.addSort("momentsRecommend", SolrQuery.ORDER.desc);
query.addSort("momentsViewNum", SolrQuery.ORDER.desc);
query.addSort("momentsLikeNum", SolrQuery.ORDER.desc);
query.addSort("momentsCreateDateTime", SolrQuery.ORDER.desc);
QueryResponse queryResponse = null;
try {
//执行查询
log.info("查询条件:{}",JSONUtil.toJsonStr(query));
queryResponse = solrClient.query(query);
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//5.取文档列表(public class SolrDocumentList extends ArrayList<SolrDocument>)
List<CommunitySearchVo> list = new ArrayList<>();
SolrDocumentList documentList = queryResponse.getResults();
for (SolrDocument solrDocument : documentList) {
CommunitySearchVo communitySearchVo = BeanUtil.toBean(solrDocument, CommunitySearchVo.class);
list.add(communitySearchVo);
}
return Result.success(list, documentList.getNumFound());
}
最终结果实现:按照预期的排序效果进行排序,且按照正常的关键字进行字段模糊搜索,50w接口相应速度也还可以在50ms左右,没有模拟高并发的情况。目前来讲,以当前的业务量足以支撑了,扛不住了再换成solr集群吧
如果有收获请点个赞吧