MongoDB

为什么使用mogodb

数据量非常大

读多写少

价值较低

mongoDB数据结构非常类似于关系型数据库(数据类型非常丰富)

一条sql语句,单张表查询一定比多张表查询要快(设计表的时候尽量将数据设计到一张表,可以冗余字段)

什么是mongodb?

分步式文件存储c++高性能数据库(内存数据库,通过引擎异步同步数据到cipan)

通过docker安装mongoDB

#进入base目录
cd /root/docker-file/base/
#批量创建启动容器,其中已经包含了redis,zookeeper,mongodb容器
docker-compose up -d
#查看容器
docker ps -a

支持的数据类型

null,布尔型,数值,字符串,日期,正则表达式,数组,内嵌文档,对象id,二进制数据

在mongodb中,存储的文档结构是类似于json的结构,称之为bson

springboot整合mongoDB

使用Spring-Data-MongoDB很简单,只需要如下几步即可:

  • 导入起步依赖

  • 编写配置信息

  • 编写实体类

导入依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.0.RELEASE</version>
</parent>

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

 

编写application.yml配置文件

spring:
  data:
    mongodb:
      uri: mongodb://192.168.136.160:27017/test  #mongodb的数据库地址和名称

 探花今日佳人

今日佳人需求介绍

今日佳人功能分析

今日佳人功能实现

在用户登录成功之后,就会进入首页,首页有今日佳人,推荐好友,探花,搜附近等功能

今日佳人会根据缘分值最大的用户,进行展现出来。缘分值的计算是由用户的行为进行打分,如点赞评论学历婚姻状态等信息组合而成。

推荐结果是由大数据工程师来生成的,所以我们只需要从结果中查询到缘分值最高的用户就可以了。

当登录探花app后,在首页可以看到和自己最匹配的佳人信息(每天推荐的佳人是不一样的)首页佳人数据,是从推荐胸每天定时根据用户基本信息以及习惯,分析推荐类似用户。推荐系统会将分析结果写入一张表中,今日佳人表

服务提供者

1.根据当前用户id查询佳人用户信息

2.根据佳人用户id查询佳人用户信息

消费者

1.controller接收今日佳人请求

2.controller调用service业务处理

a.根据当前用户id 查询一条今日佳人数据(调用服务提供者) -- recommend_user

b.如果今日佳人数据不存在,则设置一条默认假数据(为了提升用户体验)

c.根据佳人用户id调用服务查询佳人用户信息 tb_userInfo

d.根据以上调用服务结果封装Vo返回

TodayBestVo
package com.tanhua.domain.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class TodayBestVo implements Serializable {
    private Long id;
    private String avatar;
    private String nickname;
    private String gender; //性别 man woman
    private Integer age;
    private String[] tags;
    private Long fateValue; //缘分值
}

服务提供者-今日佳人

导入依赖

tanhua-domain模块的pom.xml引入mongo依赖

<!--SpringDataMongo起步依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver-sync</artifactId>
    <version>3.9.1</version>
</dependency>

RecommendUser

package com.tanhua.dubbo.api.mongo;

import com.tanhua.domain.mongo.RecommendUser;
import com.tanhua.domain.vo.PageResult;

/**
 * 佳人服务接口
 */
public interface RecommendUserApi {
    /**
     * 根据当前登录的用户id查询佳人用户表 最匹配用户对象(1条记录)
     * @param toUserId
     * @return
     */
    RecommendUser queryMaxScoreByToUserId(Long toUserId);

    /**
     * 跟当前登录用户id 分页参数 分页查询佳人列表数据
     * @param page
     * @param pagesize
     * @param currentUserId
     * @return
     */
    PageResult<RecommendUser> queryPageByUserId(Integer page, Integer pagesize, Long currentUserId);

    /**
     * 根据佳人用户id 与 当前用户id 查询缘分值
     * @param userId 佳人用户id
     * @param toUserId 当前用户id
     * @return
     */
    Double queryForScore(Long userId,Long toUserId);
}
RecommendUserApiImpl
package com.tanhua.dubbo.api.mongo;
import com.tanhua.domain.mongo.RecommendUser;
import com.tanhua.domain.vo.PageResult;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.List;

/**
 * 今日佳人服务实现类
 */
@Service
public class RecommendUserApiImpl implements RecommendUserApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 根据当前登录的用户id查询佳人用户表 最匹配用户对象(1条记录)
     * db.recommend_user.find({toUserId:1}).sort({score:-1}).limit(1);
     *
     * @param toUserId
     * @return
     */
    @Override
    public RecommendUser queryMaxScoreByToUserId(Long toUserId) {
        Query query = new Query();
        //{toUserId:1}
        query.addCriteria(Criteria.where("toUserId").is(toUserId));
        //sort({score:-1})
        //query.with(Sort.by(Sort.Direction.DESC, "score"));
        query.with(Sort.by(Sort.Direction.ASC, "userId"));
        //limit(1)
        query.limit(1);
        return mongoTemplate.findOne(query, RecommendUser.class);
    }

    /**
     * 跟当前登录用户id 分页参数 分页查询佳人列表数据
     *
     * @param page
     * @param pagesize
     * @param currentUserId
     * @return
     */
    @Override
    public PageResult<RecommendUser> queryPageByUserId(Integer page, Integer pagesize, Long currentUserId) {
        //1.查询recommendUser表总记录数
        Query query = new Query();
        query.addCriteria(Criteria.where("toUserId").is(currentUserId));//当前用户id
        query.limit(pagesize).skip((page - 1) * pagesize);
        long counts = mongoTemplate.count(query, RecommendUser.class);
        //2.查询当前页面要展示的数据
        List<RecommendUser> recommendUserList = mongoTemplate.find(query, RecommendUser.class);
        //3.将数据封装返回
        long pages = (counts / pagesize) + (counts%pagesize > 0 ? 1:0);
        return new PageResult<>(counts,(long)pagesize,pages,(long)page,recommendUserList);
    }
    /**
     * 根据佳人用户id 与 当前用户id 查询缘分值
     * @param userId 佳人用户id
     * @param toUserId 当前用户id
     * @return
     */
    @Override
    public Double queryForScore(Long userId, Long toUserId) {
        Query query = new Query();
        //{toUserId:1}
        query.addCriteria(Criteria.where("userId").is(userId).and("toUserId").is(toUserId));
        RecommendUser recommendUser = mongoTemplate.findOne(query, RecommendUser.class);
        if(recommendUser == null){
            return 99d;
        }
        return recommendUser.getScore();
    }
}

消费者

TodayBestController
package com.tanhua.server.controller;

import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.RecommendUserQueryParam;
import com.tanhua.domain.vo.TodayBestVo;
import com.tanhua.server.service.SettingService;
import com.tanhua.server.service.TodayBestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * 今日佳人控制层
 */
@RestController
@RequestMapping("/tanhua")
public class TodayBestController {

    @Autowired
    private TodayBestService todayBestService;

    /**
     * 首页-今日佳人
     */
    @RequestMapping(value = "/todayBest", method = RequestMethod.GET)
    public ResponseEntity todayBest() {
        TodayBestVo todayBestVo = todayBestService.todayBest();
        return ResponseEntity.ok(todayBestVo);
    }

    /**
     * 首页-佳人列表数据分页查询
     */
    @RequestMapping(value = "/recommendation", method = RequestMethod.GET)
    public ResponseEntity recommendation(RecommendUserQueryParam recommendUserQueryParam) {
        PageResult<TodayBestVo> pageResult = todayBestService.recommendation(recommendUserQueryParam);
        return ResponseEntity.ok(pageResult);
    }


    /**
     * 查看用户详情
     * {id}:佳人用户id
     */
    @RequestMapping(value = "/{id}/personalInfo", method = RequestMethod.GET)
    public ResponseEntity personalInfo(@PathVariable("id") Long personUserId) {
        TodayBestVo todayBestVo = todayBestService.personalInfo(personUserId);
        return ResponseEntity.ok(todayBestVo);
    }

    /**
     * 查询陌生人问题
     * userId:佳人用户id
     */
    @RequestMapping(value = "/strangerQuestions", method = RequestMethod.GET)
    public ResponseEntity strangerQuestions(Long userId) {
        String txt = todayBestService.strangerQuestions(userId);
        return ResponseEntity.ok(txt);
    }


    /**
     * 回复陌生人问题
     */
    @RequestMapping(value = "/strangerQuestions", method = RequestMethod.POST)
    public ResponseEntity strangerQuestions(@RequestBody Map params) {
        Long userId = Long.parseLong(params.get("userId").toString());
        String reply = (String) params.get("reply");//回复内容
        todayBestService.replyStrangerQuestions(userId, reply);
        return ResponseEntity.ok(null);
    }

    /**
     * 添加喜欢
     */
    @GetMapping("/{id}/love")
    public ResponseEntity addLikeUser(@PathVariable("id") String id) {
        todayBestService.addLikeUser(Long.valueOf(id));
        return ResponseEntity.ok(null);
    }

    /**
     * 添加黑名单
     */
    @GetMapping("/{id}/unlove")
    public ResponseEntity unLikeUser(@PathVariable("id") String id) {

        todayBestService.addBlackUser(Long.valueOf(id));
        return ResponseEntity.ok(null);
    }
}
TodayBestService
package com.tanhua.server.service;

import com.alibaba.fastjson.JSON;
import com.tanhua.commons.templates.HuanXinTemplate;
import com.tanhua.domain.db.BlackList;
import com.tanhua.domain.db.Question;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Friend;
import com.tanhua.domain.mongo.RecommendUser;
import com.tanhua.domain.mongo.UserLike;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.RecommendUserQueryParam;
import com.tanhua.domain.vo.TodayBestVo;
import com.tanhua.dubbo.api.db.BlackListApi;
import com.tanhua.dubbo.api.db.QuestionApi;
import com.tanhua.dubbo.api.db.UserInfoApi;
import com.tanhua.dubbo.api.mongo.FriendApi;
import com.tanhua.dubbo.api.mongo.RecommendUserApi;
import com.tanhua.dubbo.api.mongo.UserLikeApi;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 今日佳人业务处理层
 */
@Service
@Slf4j
public class TodayBestService {

    @Reference
    private RecommendUserApi recommendUserApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Reference
    private BlackListApi blackListApi;

    @Reference
    private QuestionApi questionApi;

    @Reference
    private UserLikeApi userLikeApi;

    @Reference
    private FriendApi friendApi;


    @Autowired
    private HuanXinTemplate huanXinTemplate;

    /**
     * 首页-今日佳人
     */
    public TodayBestVo todayBest() {
        Long toUserId = UserHolder.getUserId();//当前登录用户id
        //a.根据当前用户id 查询一条今日佳人数据(调用服务提供者) -- recommend_user
        RecommendUser recommendUser = recommendUserApi.queryMaxScoreByToUserId(toUserId);
        //b.如果今日佳人数据不存在,则设置一条默认假数据(为了提升用户体验)
        if (recommendUser == null) {
            //默认数据
            recommendUser = new RecommendUser();
            recommendUser.setUserId(1l);
            recommendUser.setScore(99d);
        }
        //c.根据佳人用户id调用服务查询佳人用户信息 tb_userInfo
        Long userId = recommendUser.getUserId();//佳人用户id
        UserInfo userInfo = userInfoApi.queryUserInfo(userId);
        //d.根据以上调用服务结果封装Vo返回
        TodayBestVo todayBestVo = new TodayBestVo();
        BeanUtils.copyProperties(userInfo, todayBestVo);
        //设置tags
        if (!StringUtils.isEmpty(userInfo.getTags())) {
            todayBestVo.setTags(userInfo.getTags().split(","));
        }
        //设置缘分值
        todayBestVo.setFateValue(recommendUser.getScore().longValue());
        return todayBestVo;
    }

    /**
     * 首页-佳人列表数据分页查询
     */
    public PageResult<TodayBestVo> recommendation(RecommendUserQueryParam param) {
        //定义返回PageResultVo
        PageResult<TodayBestVo> voPageResult = new PageResult<>();

        Long currentUserId = UserHolder.getUserId();
        //1.跟当前登录用户id 分页参数 分页查询佳人列表数据
        PageResult<RecommendUser> pageResult = recommendUserApi.queryPageByUserId(param.getPage(), param.getPagesize(), currentUserId);
        //2.如果数据为空,设置默认数据
        List<RecommendUser> recommendUserList = new ArrayList<>();
        if (pageResult == null || CollectionUtils.isEmpty(pageResult.getItems())) {
            recommendUserList = defaultRecommend();
        } else {
            recommendUserList = pageResult.getItems();
        }
        //3.根据userId查询userInfo
        //4.将List<RecommendUser>转为List<TodayBestVo>
        List<TodayBestVo> todayBestVoList = new ArrayList<>();
        for (RecommendUser recommendUser : recommendUserList) {
            //根据以上调用服务结果封装Vo返回
            TodayBestVo todayBestVo = new TodayBestVo();
            Long userId = recommendUser.getUserId();//佳人用户id
            UserInfo userInfo = userInfoApi.queryUserInfo(userId);
            BeanUtils.copyProperties(userInfo, todayBestVo);
            //设置tags
            if (!StringUtils.isEmpty(userInfo.getTags())) {
                todayBestVo.setTags(userInfo.getTags().split(","));
            }
            //设置缘分值
            todayBestVo.setFateValue(recommendUser.getScore().longValue());
            todayBestVoList.add(todayBestVo);
        }
        //4.将数据封装返回
        BeanUtils.copyProperties(pageResult, voPageResult);//copy分页数据
        voPageResult.setItems(todayBestVoList);//将todayBestVoList设置到返回的Vo中
        return voPageResult;
    }


    //构造默认数据
    private List<RecommendUser> defaultRecommend() {
        String ids = "1,2,3,4,5,6,7,8,9,10";
        List<RecommendUser> records = new ArrayList<>();
        for (String id : ids.split(",")) {
            RecommendUser recommendUser = new RecommendUser();
            recommendUser.setUserId(Long.valueOf(id));
            recommendUser.setScore(RandomUtils.nextDouble(70, 98));
            records.add(recommendUser);
        }
        return records;
    }

    /**
     * 查看用户详情
     * {id}:佳人用户id
     */
    public TodayBestVo personalInfo(Long personUserId) {

        // a.根据佳人用户id查询userInfo
        UserInfo userInfo = userInfoApi.queryUserInfo(personUserId);
        //  b.调用服务获取缘分值
        Double score = recommendUserApi.queryForScore(personUserId, UserHolder.getUserId());
        //  c.封装vo
        TodayBestVo vo = new TodayBestVo();
        BeanUtils.copyProperties(userInfo, vo);
        if (userInfo != null && !StringUtils.isEmpty(userInfo.getTags())) {
            vo.setTags(userInfo.getTags().split(","));
        }
        vo.setFateValue(score.longValue());//缘分值
        return vo;

    }

    /**
     * 查询陌生人问题
     * userId:佳人用户id
     */
    public String strangerQuestions(Long userId) {
        String txt = "约吗?";
        Question question = questionApi.queryByUserId(userId);
        if (question != null && !StringUtils.isEmpty(question.getTxt())) {
            txt = question.getTxt();
        }
        return txt;
    }

    /**
     * 回复陌生人问题
     */
    public void replyStrangerQuestions(Long userId, String reply) {
        //a.UserHolder.getuserId()获取当前用户id
        Long currentUserId = UserHolder.getUserId();//当前用户id
        //b.根据当前登录用户id 查询userInfo 获取昵称
        UserInfo userInfo = userInfoApi.queryUserInfo(currentUserId);
        String nickname = userInfo.getNickname();

        //c.根据佳人用户id查询问题
        Question question = questionApi.queryByUserId(userId);
        String txt = "约吗?";
        if (question != null && !StringUtils.isEmpty(question.getTxt())) {
            txt = question.getTxt();
        }
        //d.将以上数据封装Map 并将Map转为String字符串
        Map<String, String> map = new HashMap();
        map.put("userId", currentUserId.toString());//当前用户id
        map.put("nickname", nickname);//当前用户昵称
        map.put("strangerQuestion", txt);//佳人问题
        map.put("reply", reply);//当前用户的回复
        String message = JSON.toJSONString(map); //将map转为message消息
        //e.调用环信云发送消息给userId佳人用户id target:佳人用户id msg:消息内容
        huanXinTemplate.sendMsg(userId.toString(), message);
        log.debug("用户{}发送消息给用户{},内容是{}", currentUserId, userId, message);
    }

    /**
     * 添加喜欢
     */
    public void addLikeUser(Long id) {
        Long userId = UserHolder.getUserId();//当前用户Id
        UserLike userLike = new UserLike();

        userLike.setUserId(userId);
        userLike.setLikeUserId(id);

        //添加喜欢的用户
        userLikeApi.addLikeUser(userLike);

        //查询对方是否喜欢我
        UserLike user = userLikeApi.findOne(id, userId);
        //判断,如果喜欢则成为好友
        if (user != null) {
            Friend friend = new Friend();
            friend.setUserId(userId);
            friend.setFriendId(id);

            friendApi.saveFriend(friend);
        }
    }

    /**
     * 添加黑名单
     */
    public void addBlackUser(Long id) {
        Long userId = UserHolder.getUserId();//当前用户Id

        BlackList user = blackListApi.findOne(userId, id);
        if (user == null) {
            BlackList blackList = new BlackList();
            blackList.setUserId(userId);
            blackList.setBlackUserId(id);
            blackListApi.addBlackUser(blackList);
        }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值