1、首页推荐
1.1、接口分析
地址:http://192.168.136.160:3000/project/19/interface/api/118
响应:
1. { 2. "counts": 4698, 3. "pagesize": 20, 4. "pages": 58, 5. "page": 16, 6. "items": [ 7. { 8. "id": 1011, 9. "avatar": "assets/images/avatar_2.png", 10. "nickname": "黑马小妹", 11. "gender": "woman", 12. "age": 23, 13. "tags": [ 14. "本科", 15. "年龄相仿", 16. "单身" 17. ], 18. "fateValue": 96 19. }, 20. { 21. "id": 2495, 22. "avatar": "assets/images/avatar_1.png", 23. "nickname": "米朵妹妹", 24. "gender": "man", 25. "age": 28, 26. "tags": [ 27. "年龄相仿", 28. "本科", 29. "单身" 30. ], 31. "fateValue": 87 32. }, 33. { 34. "id": 5708, 35. "avatar": "assets/images/avatar_4.png", 36. "nickname": "黑马小妹", 37. "gender": "man", 38. "age": 24, 39. "tags": [ 40. "单身", 41. "本科", 42. "年龄相仿" 43. ], 44. "fateValue": 94 45. }, 46. { 47. "id": 4768, 48. "avatar": "assets/images/avatar_3.png", 49. "nickname": "黑马小妹", 50. "gender": "man", 51. "age": 24, 52. "tags": [ 53. "年龄相仿", 54. "单身", 55. "本科" 56. ], 57. "fateValue": 80 58. } 59. ] 60. }
1.2、功能实现
1.2.1 controller
TanhuaController
编写推荐列表方法
1. /** 2. * 查询分页推荐好友列表 3. */ 4. @GetMapping("/recommendation") 5. public ResponseEntity recommendation(RecommendUserDto dto) { 6. PageResult pr = tanhuaService.recommendation(dto); 7. return ResponseEntity.ok(pr); 8. }
1.2.2 service
TanhuaService
编写推荐列表方法
1. //查询分页推荐好友列表 2. public PageResult recommendation(RecommendUserDto dto) { 3. //1、获取用户id 4. Long userId = UserHolder.getUserId(); 5. //2、调用recommendUserApi分页查询数据列表(PageResult -- RecommendUser) 6. PageResult pr = recommendUserApi.queryRecommendUserList(dto.getPage(),dto.getPagesize(),userId); 7. //3、获取分页中的RecommendUser数据列表 8. List<RecommendUser> items = (List<RecommendUser>) pr.getItems(); 9. //4、判断列表是否为空 10. if(items == null || items.size() <=0) { 11. return pr; 12. } 13. //5、提取所有推荐的用户id列表 14. List<Long> ids = CollUtil.getFieldValues(items, "userId", Long.class); 15. UserInfo userInfo = new UserInfo(); 16. userInfo.setAge(dto.getAge()); 17. userInfo.setGender(dto.getGender()); 18. //6、构建查询条件,批量查询所有的用户详情 19. Map<Long, UserInfo> map = userInfoApi.findByIds(ids, userInfo); 20. //7、循环推荐的数据列表,构建vo对象 21. List<TodayBest> list = new ArrayList<>(); 22. for (RecommendUser item : items) { 23. UserInfo info = map.get(item.getUserId()); 24. if(info!=null) { 25. TodayBest vo = TodayBest.init(info, item); 26. list.add(vo); 27. } 28. } 29. //8、构造返回值 30. pr.setItems(list); 31. return pr; 32. }
1.2.3 API接口
在RecommendUserApi
接口和RecommendUserApiImpl
实现类中添加方法查询
1. //分页查询 2. public PageResult queryRecommendUserList(Integer page, Integer pagesize, Long toUserId) { 3. //1、构建Criteria对象 4. Criteria criteria = Criteria.where("toUserId").is(toUserId); 5. //2、创建Query对象 6. Query query = Query.query(criteria).with(Sort.by(Sort.Order.desc("score"))).limit(pagesize) 7. .skip((page - 1) * pagesize); 8. //3、调用mongoTemplate查询 9. List<RecommendUser> list = mongoTemplate.find(query, RecommendUser.class); 10. long count = mongoTemplate.count(query, RecommendUser.class); 11. //4、构建返回值PageResult 12. return new PageResult(page,pagesize,count,list); 13. }
1.2.4 请求dto对象
1. import lombok.AllArgsConstructor; 2. import lombok.Data; 3. import lombok.NoArgsConstructor; 4. 5. @Data 6. @NoArgsConstructor 7. @AllArgsConstructor 8. public class RecommendUserDto { 9. 10. private Integer page = 1; //当前页数 11. private Integer pagesize = 10; //页尺寸 12. private String gender; //性别 man woman 13. private String lastLogin; //近期登陆时间 14. private Integer age; //年龄 15. private String city; //居住地 16. private String education; //学历 17. }
2、MongoDB集群
3、圈子功能
2.1、功能说明
探花交友项目中的圈子功能,类似微信的朋友圈,基本的功能为:发布动态、浏览好友动态、浏览推荐动态、点赞、评论、喜欢等功能。
发布:
1.2、实现方案分析
对于圈子功能的实现,我们需要对它的功能特点做分析:
- 数据量会随着用户数增大而增大
- 读多写少
- 非好友看不到其动态内容
- ……
针对以上特点,我们来分析一下:
- 对于数据量大而言,显然不能够使用关系型数据库进行存储,我们需要通过MongoDB进行存储
- 对于读多写少的应用,需要减少读取的成本
- 比如说,一条SQL语句,单张表查询一定比多张表查询要快
- 对于每个人数据在存储层面最好做到相互隔离,这样的话就不会有影响
所以对于存储而言,主要是核心的4张表:
- 发布表:记录了所有用户的发布的东西信息,如图片、视频等。
- 自己时间线:相册是每个用户独立的,记录了该用户所发布的所有内容。
- 好友时间线:所谓“刷朋友圈”,就是刷时间线,就是一个用户所有的朋友的发布内容。
- 好友表:记录好友关系
1.3、技术方案(重点)
根据之前我们的分析,对于技术方案而言,将采用MongoDB+Redis来实现,其中MongoDB负责存储,Redis负责缓存数据。
1.4、表结构设计
发布表:动态总记录表(记录每个人发送的动态详情)
1. #表名:movement 2. { 3. "_id": ObjectId("5e82dc416401952928c211d8"), 4. "pid": NumberLong("10064"), 5. "userId": NumberLong("6"), 6. "textContent": "最悲伤却又是最痛苦的谎言,就是我还好,没有关系。", 7. "medias": [ 8. "https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/photo/7/1.jpg", 9. "https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/photo/7/1564567349498.jpg", 10. "https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/photo/7/1564567352977.jpg", 11. "https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/photo/7/1564567360406.jpg" 12. ], 13. "longitude": "121.588627", 14. "latitude": "30.935781", 15. "state": NumberInt("0"), 16. "locationName": "中国上海市奉贤区人民路445弄", 17. "created": NumberLong("1585634369493"), 18. "_class": "com.tanhua.dubbo.server.pojo.Publish" 19. }
好友时间线表:记录当前好友发布的动态数据
1. #表名:movement_timeline 2. { 3. "_id": ObjectId("609cf6538743d448c02c61f0"), 4. "movementId": ObjectId("609cf6538743d448c02c61ef"), 5. "userId": NumberLong("106"), 6. "friendId": NumberLong("1"), 7. "created": NumberLong("1620899411043"), 8. "_class": "com.tanhua.model.mongo.MovementTimeLine" 9. }
好友关系表:记录好友的双向关系(双向)
1. #表名:friend 2. { 3. "_id": ObjectId("6018bc055098b2230031e2da"), 4. "created": NumberLong("1612233733056"), 5. "userId": NumberLong("1"), 6. "friendId": NumberLong("106"), 7. "_class": "com.itheima.domain.mongo.Friend" 8. }