首页 技术 正文
技术 2022年11月19日
0 收藏 870 点赞 4,467 浏览 5136 个字

MongoDB简介

文章评论数据分析

相较于一般数据,文章评论一般有如下特点:

  1. 数据量巨大。通常评论量要比帖子、文章大很多
  2. 写入操作频繁。
  3. 价值较低。一般来说,我们的主要目标还是在帖子(文章)本身。

基于上述要求,很明显,我们的传统关系型数据库如mysql是不符合要求的,因此我们需要使用一款nosql数据库,这里我们使用MongoDB来进行评论管理。

MongoDB介绍

MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。

MongoDB特点

Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

它的特点是高性能、易部署、易使用,存储数据非常方便。主要功能特性有:

  1. 面向集合存储,易存储对象类型的数据。
  2. 模式自由。
  3. 支持动态查询。
  4. 支持完全索引,包含内部对象。
  5. 支持查询。
  6. 支持复制和故障恢复。
  7. 使用高效的二进制数据存储,包括大型对象(如视频等)。
  8. 自动处理碎片,以支持云计算层次的扩展性。
  9. 支持RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。
  10. 文件存储格式为BSON(一种JSON的扩展)。

MongoDB体系结构

MongoDB 的逻辑结构是一种层次结构。主要由:文档(document)、集合(collection)、数据库(database)这三部分组成的。逻辑结构是面向用户的,用户使用 MongoDB 开发应用程序使用的就是逻辑结构。

  1. MongoDB 的文档(document),相当于关系数据库中的一行记录。
  2. 多个文档组成一个集合(collection),相当于关系数据库的表。
  3. 多个集合(collection),逻辑上组织在一起,就是数据库(database)。
  4. 一个 MongoDB 实例支持多个数据库(database)。
MongoDB 关系型数据库Mysql
数据库(database) 数据库(database)
集合(collections) 表(table)
文档(document) 行(row)

MongoDB数据类型

数据类型 描述
String 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。
Integer 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。
Boolean 布尔值。用于存储布尔值(真/假)。
Double 双精度浮点值。用于存储浮点值。
Array 用于将数组或列表或多个值存储为一个键。
Timestamp 时间戳。记录文档修改或添加的具体时间。
Object 用于内嵌文档。
Null 用于创建空值。
Date 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。
Object ID 对象 ID。用于创建文档的 ID。
Binary Data 二进制数据。用于存储二进制数据。
Code 代码类型。用于在文档中存储 JavaScript 代码。
Regular expression 正则表达式类型。用于存储正则表达式。

特殊说明:

  1. ObjectId

    ObjectId 类似唯一主键,可以很快的去生成和排序,包含 12 bytes,含义是:

    • 前 4 个字节表示创建 unix 时间戳,格林尼治时间 UTC 时间,比北京时间晚了 8 个小时
    • 接下来的 3 个字节是机器标识码
    • 紧接的两个字节由进程 id 组成 PID
    • 最后三个字节是随机数

    MongoDB 中存储的文档必须有一个 _id 键。这个键的值可以是任何类型的,默认是个 ObjectId 对象,使用的时候为了保持查询效率的高效一般我们不动它。

  2. 时间戳

    BSON 有一个特殊的时间戳类型,与普通的日期类型不相关。时间戳值是一个 64 位的值。其中:

    • 前32位是一个 time_t 值【与Unix新纪元(1970年1月1日)相差的秒数】
    • 后32位是在某秒中操作的一个递增的序数

    在单个 mongod 实例中,时间戳值通常是唯一的。

  3. 日期

    表示当前距离 Unix新纪元(1970年1月1日)的毫秒数。日期类型是有符号的, 负数表示 1970 年之前的日期。

MongoDB基本使用

Docker中安装MongoDB

在Linux虚拟机中创建mongo容器,命令如下:

docker run -id --name mongo -p 27017:27017 mongo

默认端口就是27017 (redis默认端口6379,mysql默认端口3306)

选择和创建数据库的语法格式:

use 数据库名称

如果数据库存在则选择该数据库,如果数据库不存在则自动创建。以下语句创建commentdb数据库:

use commentdb

评论功能实现

评论集合结构

专栏文章评论 comment
字段名称 字段含义 字段类型 备注
_id ID 文本
articleid 文章ID 文本
content 评论内容 文本
userid 评论人ID 文本
parentid 评论ID 文本 如果为0表示文章的顶级评论
publishdate 评论日期 日期
thumbup 点赞数 数字

需要实现以下功能:

  1. 基本增删改查API
  2. 根据文章id查询评论
  3. 评论点赞

项目中环境准备

添加依赖

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

添加配置文件

  data:
mongodb:
database: commentdb
host: 192.168.200.128

SpringDataMongoDB是SpringData家族成员之一,用于操作MongoDb的持久层框架,封装了底层的mongodb-driver。

功能实现

创建实体类:

public class Comment implements Serializable {
@Id
private String _id;
private String articleid;
private String content;
private String userid;
private String parentid;
private Date publishdate;
private Integer thumbup;
//getter and setter....
}

尽管这个命名不符合规范,不过主键名称还是要叫_id

Dao接口:

不要和Mybatis的接口放一块

直接继承springdata提供的MongoRepository,可以使用其提供的增删改查

public interface CommentRepository extends MongoRepository<Comment, String> {
} //泛型分别为实体类和主键类型

Service:

@Service
public class CommentService {
@Autowired
private IdWorker idWorker;
@Autowired
private CommentRepository commentRepository; //根据id查询
public Comment findById(String id) {
return commentRepository.findById(id).get();
}
//查询所有
public List<Comment> findAll() {
return commentRepository.findAll();
}
//保存数据
public void save(Comment comment) {
String id = idWorker.nextId() + "";
comment.set_id(id);
//初始化数据
comment.setPublishdate(new Date());
comment.setThumbup(0);
commentRepository.save(comment);
}
//修改数据
public void update(Comment comment) {
commentRepository.save(comment);
}
//删除数据
public void deleteById(String id) {
commentRepository.deleteById(id);
}
}

一般来说,增删改这些操作直接继承的接口中的方法就够用了,但是查询方面,只有与主键相关的方法,想要根据其他属性查询就我们需要自己写一些方法,但是不需要我们自己去实现,只需要保持命名规范就行了

例如根据文章id查询评论,这里的文章id不是主键,需要我们自己写方法

编写Dao

public interface CommentRepository extends MongoRepository<Comment, String> {
//根据文章id查询评论列表
List<Comment> findByArticleid(String articleId);
}

这种findByArticleid的规范命名格式springdata会帮我们实现对应的方法

评论点赞

评论点赞无非是让点赞字段加一。这里要注意的是前往不要使用那种先查询出点赞数,在外面给它加一后再赋值回去的方法,这样并发处理的时候会出问题。因此我们需要让该字段自增一位就行了。

这里使用继承的接口就不行了,需要我们自己构造条件,使用MongoTemplate

@Autowired
private MongoTemplate mongoTemplate;
public void thumbup(String id) {
//修改条件
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(id));
//修改的数据
Update update = new Update();
//在原来的基础上加一
update.inc("thumbup", 1);
mongoTemplate.updateFirst(query, update, "comment");
}

关于MongoTemplate的用法就难得讨论了,暂时会个自增就行了。

重复点赞问题

在上面的点赞问题处理中,我们并没有对点赞条件进行限制,这就意味着用户可以一直点赞。这显然是不合理的,因为首先想到的是我们还需要来存储用户对某一评论的点赞情况。

这一问题又是操作频繁、数据量大的数据处理,因此关系型数据库又排除在外,只能使用nosql了,这里只有一个点赞关系的数据要存储,为了追求高速度,我们使用redis存储点赞信息。

添加依赖:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

docker中创建容器:

docker run -id --name=tensquare_redis -p 6379:6379 redis

默认端口6379

配置文件添加上配置:

  redis:
host: 192.168.200.128

修改Controller:

使用RedisTemplate操作redis

@Autowired
private RedisTemplate redisTemplate;
//评论点赞
@RequestMapping(value = "thumbup/{id}", method = RequestMethod.PUT)
public Result thumbup(@PathVariable String id) {
//模拟获取到了用户id
String userid = "123";
//在redis中查询用户是否已经点赞
Object result = redisTemplate.opsForValue().get("thumbup_" + userid + "_" + id);
//如果点赞不能重复点赞
if (result != null) {
return new Result(false, StatusCode.REMOTEERROR, "不能重复点赞");
}
//如果没有点赞,可以进行点赞操作
commentService.thumbup(id);
//保存点赞记录
redisTemplate.opsForValue().set("thumbup_" + userid + "_" + id, 1);
return new Result(true, StatusCode.OK, "点赞成功");
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,076
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,552
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,400
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,176
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,812
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,894