关于补充需求中articles索引结构的一些问题

来源:15-17 redis拓展作业 - 首页热闻实现思路

慕勒3498910

2023-04-05

老师:你好。根据课程视频中提供的"首页热闻列表接口"的实现思路,我这边自己先按照思路实现了一下,然后,在实现中遇到有几个问题,想请教一下。整体来说通过阅读文章详情的时候,添加阅读数的方法里面,我这边设置ZSET类型的KEY="redis_article_hot_article_score",最终根据SCORE从高到底取5个articleId,然后,再从ES中拿到5个articleId对应DOC数据返回过程中,有遇到以下几个问题:

1、首先,遇到这样一个问题,就是之前articles索引的id的类型,之前设置为text,好像有些不妥,我感觉应该设置为"keyword"类型好像更好一些。

https://www.imooc.com/wiki/imoocnewsarchitect/f234r32r23.html

http://img.mukewang.com/szimg/642d8abf092b3c4610850469.jpg

因为,最后,当我这边想用term或者terms来进行类似SQL查询中的IN语法匹配查询的时候,发现这个text类型,没法匹配上,得用matchQuery了,感觉没有必要。相关代码如下:

@Override
public List<ArticleEO> queryEsHotArticleList() { 
	// 从REDIS中获取分数由高到底的前5个articleId
	Set<String> articleIds = redis.reverseZsetRange(REDIS_ARTICLE_HOT_ARTICLE_SCORE,
							0,
							REDIS_ARTICLE_HOT_ARTICLE_NUM - 1);

	// FIXME:
//        List<String> articleIds = Arrays.asList("230405FSD2D5WSFW",
//                                                "230405FS91XNK4ZC");

	BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
	// 想通过termsQuery来实现类似SQL中的IN查询
	// boolQuery.must(QueryBuilders.termsQuery("id", articleIds));
	
	// 想通过循环termQuery来实现类似SQL中的IN查询,也就是OR查询
	if (articleIds != null && articleIds.size() > 0)
	{
		for (String articleId: articleIds)
		{
			boolQuery.should(QueryBuilders.termQuery("id", articleId));
		}
	}

	SearchQuery searchQuery = new NativeSearchQueryBuilder().
				      withQuery(boolQuery).
				      build();

	System.out.println(searchQuery.getQuery());

	List<ArticleEO> articleEsList = esTemplate.queryForList(searchQuery, ArticleEO.class);

	return articleEsList;
}

2、第2个问题,就是在对这个索引articles字段id类型修改的时候,我发现好像和数据库表字段类型修改对比,要麻烦得多。涉及到索引重建,原来的articles是没法用了,好像得删掉原来的articles,再重新建立新的articles,然后,才能修改既有字段的类型,字段名,包括新增新字段和删除旧字段。这块如果是真实项目的话,势必就涉及到大量旧数据的迁移了,感觉可能实际项目里面问题点更多,这块也是感觉挺麻烦的,实际做这个索引重建工作的话,一般有什么比较好的实现方案来平稳过渡上线流程呢?

3、关于列表数据的排序问题,比如:在REDIS中,可以看到

articleId:230405FWMDRYC1KP,score分数更高

http://img.mukewang.com/szimg/642d8ddc09d3d52204610158.jpg

然而,最终的列表接口返回数据的时候,分数更高的articleId却排到了第2位,感觉这个实现就不太好了。

http://img.mukewang.com/szimg/642d8e460953357e08730612.jpg

我这边DEBUG了一下,就是代码里面拿到的articleId的顺序也是符合score从高到底排序的。

http://img.mukewang.com/szimg/642d8ec609a4897c14980653.jpg

然而,最后经过ES这边不论是terms还是逐个term的匹配,都没法拿到预期的排序列表数据,用articleId字段来做SORT也不对,怎么才能按照和REDIS中相同的排序顺序从ES中拿到相同顺序的数据呢?我的想法是在articles索引里面再添加一个类似readCounts的字段,其实也就是阅读数,然后,在每次修改ZSET的时候,也修改一下articles中的readCounts的值,最后根据readCounts来进行降序排序。不然,好像没法拿到预期的排序了,但是,这么做又感到很多余且很麻烦,又得修改索引结构了,而且,又有点重复修改两块数据源(ES和REDIS)的意味,不知道老师,您这边有什么建议方案呢?

写回答

1回答

风间影月

2023-04-05

老铁,能不能一个个来?这小作文看得我头疼😂

0
1
慕勒3498910
不好意思哈!实在都是关联问题,分开提吧,感觉也不太合适。主要是问题3,希望老师帮忙看一下,我试了几下,都没法得到最理想的效果。
2023-04-05
共1条回复

Spring Cloud 进阶 Alibaba 微服务体系自媒体实战

一课收获分布式系统开发,微服务核心技术和中间件企业生产落地

1113 学习 · 896 问题

查看课程