elasticsearch 聚合后分页的解决方案

1.需求

 我们网站要实现全文检索的功能,业务是这样的,有两个对象,一个课程包,一个视频,课程包下可以有很多个视频,相当于是1对多的关系,全文检索的关键词是根据视频名去检索的,而不是课程包名称,但是搜索的结果页展示的是课程包列表(分页),如果用关系型数据库,比如mysql,那么一般查询sql看起来应该l是这样的:

select * from t_package_video where video_name like '%xxx%' group by package_id limit 0,10

在elasticsearch中group by就相当于是聚合中的桶,例如把人类的肤色进行聚合,那么结果出来的就是3个桶,黄桶,白桶和黑桶。

但是elasticsearch 中的聚合是不支持聚合后分页的,就比如我上面这个需求是没有办法直接实现。

2.解决

2.1.通过聚合中的size属性解决(分不了页)

我是利用springboot集成的elasticsearch,所以他的代码是这样的:

SearchQuery searchQuery = queryBuilder.withQuery(boolQuery)
				.withSort(new ScoreSortBuilder())
				.addAggregation(AggregationBuilders.terms("packageId").field("packageId").size(1)) 
				.build();

terms表示桶聚合,聚合目前有4中,桶聚合只是其中一种,可以去官网查询。

其中的参数就是给这个聚合赋予一个名字,而field则是指定对索引中的哪个字段进行聚合,我这里就是packageId.

后面的size属性非常重要,这个是指桶的个数,就是你要返回几个桶,这个参数就可以当做是你的pageSize使用,但是却指定不了页码,因为方法里面没有from等指定页码或者开始坐标的方法。当你获取返回值后,每个桶就是你要的一条数据,通过每个桶的key查找出该key的第一条记录

2.2. 改变索引的字段结构(完美解决,但是不适合所有的情况)

我一开始设置的索引字段就是,packageId,videoName即最常见的逻辑,假设一个课程包下有3个视频,那么就会被添加3个document,但是这种结构就会出现我们上面说的聚合后分不了页的情况,所以我换了一种结构,即packageId,videoNames,注意多了一个s,即将3个视频的名称合在一起,这样的话,我就不用去做聚合操作了,直接分页就行了,但是这种方法不是万能的,因为我的搜索结果页只需要课程包的信息,并不需要视频的名称或者视频的其他信息,所以我可以合并视频名,但是一细想,就算需要每个课程包下的视频信息又怎样,我通过这种方式已经获取了分页的课程包列表,我再在数据库中查出每个课程包下的视频也是可以的,所以只要灵活变通,应该都没啥问题

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巴中第一皇子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值