MongoDB学习笔记
tips:MongoDB
文章目录
一、MongoDB基本概念及原理
- MongoDB是一个分布式文件存储的NoSQL数据库,C++编写。
- 主要针对Web应用提供可扩展,高可用数据库存储解决方案。
- MongoDB是最像关系型数据库的NoSQL数据,在某些方面可以替换MySQL。
- MongoDB存储数据是key-value结构的BSON(二进制JSON)文档。
注释:
1、存储类型:键值型(key-value)、文档型(document)
2、MongoDB就是文档型NoSQL数据库,它文档中的数据是以类似JSON的BSON格式进行存储的。我们拿JSON去理解,JSON中的数据,都是key-value,key一般都是String类型的,而value就多种多样了。记住value中可以再存储一个文档。
(一)MongoDB与SQL对比
SQL概念 | MongoDB概念 | 说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表连接、MongoDB不支持 | |
primary key | primary key | 主键、MongoDB自动将_id字段设置为主键 |
具体实例如下:
SQL表示:
id | user_name | age | city | |
---|---|---|---|---|
1 | Mark Hanks | mark@abc.com | 25 | Los Angeles |
2 | Richard Peter | richard@abc.com | 31 | Dallas |
MongoDB表示:
{
"_id":ObjectId("5146bb52d8524270060001f2"),
"age":25,
"city":"Los Angeles",
"email":"mark@abc.com",
"user_name":"Mark Hanks"
}
{
"_id":ObjectId("5146bb52d8524270060001f3"),
"age":31,
"city":"Dallas",
"email":"richard@abc.com",
"user_name":"Richard Peter"
}
注释:
1、MongoDB不需要设置相同的字段
2、相同的字段不需要拥有相同的类型
如city和city,可以换成city和country,或者同样的age一个是int类型,一个是string类型。
3、文档中的键值对是有序的且不能重复,区分大小写。
(二)MongoDB集合
1.集合相当于SQL的数据库表,但是集合没有固定格式,意味着可以插入不同的格式和类型的数据,但通常境况要保持一定的关联性,如:
{"site":"www.baidu.com"}
{"site":"www.google.com","name":"Google"}
{"site":"www.kaikeba.com","name":"开课吧","num":5}
2.当第一个文档插入时,集合就被创建了。
3.一个集合collection中的所有field是collection中所有document中阿博涵的field的并集。
(三)MongoDB数据类型
(四)MongoDB底层原理
MongoDB的部署方案有三种:单机部署、主从部署、主备部署(副本集)、分片部署、副本集与分片混合部署。
- 单机部署:顾名思义就是只部署一个服务。
- 主从部署:master-slaver,一个主节点和多个从节点,主节点提供读写,从节点提供读。不同节点数据一致。MongoDB要在配置文件里面指明主节点和从节点对应的关系,且master节点故障的时候,不能及时的自动的切换到slaves节点,需要手动干预。
- 主备部署:与主从区别是不用指明主从关系,会自动选出一个主节点。
- 分片部署:分为不同的分片服务器,但是分片节点的数据不一致。
- 副本集与分片混合部署:分为不同的分片,同时每个分片有多个副本集、
二、MongoDB安装及常用命令
(一)MongoDB安装
安装步骤:
#获取包的下载地址,选择版本(3.6)、操作系统(RHEL7.0)和包类型(TGZ),并解压缩
tar -zxvf mongodb-linux-x86_64-rhel70-3.6.11.tgz
mv mongodb-linux-x86_64-rhel70-3.6.11 mongodb
#文件下面的命令
-rwxr-xr-x. 1 root root 13549720 Feb 28 2019 bsondump
-rwxr-xr-x. 1 root root 7770 Feb 28 2019 install_compass
-rwxr-xr-x. 1 root root 33775440 Feb 28 2019 mongo 连接客户端的
-rwxr-xr-x. 1 root root 59622984 Feb 28 2019 mongod 启动服务
-rwxr-xr-x. 1 root root 14415040 Feb 28 2019 mongodump 备份
-rwxr-xr-x. 1 root root 13975624 Feb 28 2019 mongoexport 导出
-rwxr-xr-x. 1 root root 13843944 Feb 28 2019 mongofiles
-rwxr-xr-x. 1 root root 14116872 Feb 28 2019 mongoimport 导入
-rwxr-xr-x. 1 root root 59127656 Feb 28 2019 mongoperf
-rwxr-xr-x. 1 root root 17768752 Feb 28 2019 mongoreplay
-rwxr-xr-x. 1 root root 14450600 Feb 28 2019 mongorestore 备份加载
-rwxr-xr-x. 1 root root 34236048 Feb 28 2019 mongos 启动路由服务
-rwxr-xr-x. 1 root root 14117952 Feb 28 2019 mongostat 性能检测
-rwxr-xr-x. 1 root root 13744056 Feb 28 2019 mongotop 性能检测
#创建data目录,MongoDB默认数据目录,如果不创建报错,或者配置文件里面指定路径,路径必须存在
mkdir -p /data/db
#配置环境变量,配置之后可以在任意目录执行MongoDB脚本
vim /etc/profile
export PATH=$JAVA_HOME/bin:/root/mongodb/mongodb/bin:$PATH
source /etc/profile
#启动MongoDB 默认端口27017
mongod &
#进入MongoDB命令行
mongo
#通过配置文件方式启动,否则只能本地访问,外网访问不了
vim mongodb.cfg
#数据库文件位置
dbpath=/root/mongodb/mongodb/singleton/data
#日志文件位置
logpath=/root/mongodb/mongodb/singleton/logs/mongodb.log
# 以追加方式写入日志
logappend=true
# 是否以守护进程方式运行
fork=true
#绑定客户端访问的ip 0.0.0.0 不绑定ip
bind_ip=192.168.203.149
# 默认27017
port=27017
#创建data目录和日志目录
mkdir -p /root/mongodb/mongodb/singleton/data
mkdir -p /root/mongodb/mongodb/singleton/logs
#启动MongoDB
./mongod -f ../singleton/mongodb.cfg
#连接MongoDB
./mongo 192.168.203.149:27017
(二)MongoDB常用命令
#简单命令介绍
show dbs 显示所有数据库
use mymongo 使用mymongo数据库,名称可以没有在show dbs里面现实
db 显示当前数据库
db.mycollection.insert({name:"james",age:"38"}) 插入数据,同时也将collection创建好了,同时数据库也被创新了,此时show dbs会看到mymongo
db.dropDatabase() 删除当前所在的数据库
show collections 显示所有集合名称
#创建集合
db.createCollection(name, options)
#删除集合
db.mycollection.drop() 删除mycollection集合
#插入文档
db.mycollection.insert(document)
var document = {name:"linda",age:"54"}
db.mycollection.insert(document)
#删除文档
db.mycollection.remove(
<query>,
<justOne>
)
#查询文档
> db.mycollection.find(query, projection)
{ "_id" : ObjectId("5e7452b32390c490805afc36"), "name" : "james", "age" : "38" }
{ "_id" : ObjectId("5e7459c42390c490805afc37"), "name" : "linda", "age" : "54" }
> db.mycollection.find().pretty() 美观展示
{
"_id" : ObjectId("5e7452b32390c490805afc36"),
"name" : "james",
"age" : "38"
}
{
"_id" : ObjectId("5e7459c42390c490805afc37"),
"name" : "linda",
"age" : "54"
}
> db.mycollection.find().limit() 只展示某几条
> db.mycollection.find({},{"name":1,_id:0}) 显示固定域
{ "name" : "james" }
{ "name" : "linda" }
> db.mycollection.find().skip(1).limit(1) 可以用来做分页
> db.mycollection.find().sort({"age":1}) 根据age升序排序
> db.mycollection.find().sort({"age":-1}) 根据age降序排序
#创建索引
db.mycollection.createIndex({age:1}) 1为升序索引,-1位降序索引
#查看索引
> db.mycollection.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_", #默认为主键添加索引
"ns" : "kkb.mycollection"
}
]
#删除索引
db.mycollection.dropIndexes() 删除所有索引
db.mycollection.totalIndexSize() 查看索引大小
db.mycollection.dropIndex("age_1") 删除name为age_1的索引
三、MongoDB Java客户端——MongoDB Java Driver
(一)pom文件配置
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.10.1</version>
</dependency>
(二)Java测试类
package com.kkb.mongodb.official.demo;
import java.util.ArrayList;
import java.util.List;
import org.bson.Document;
import org.junit.Before;
import org.junit.Test;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoIterable;
import com.mongodb.client.model.Filters;
public class MongodbDemo {
private MongoClient client;
//初始化client
@Before
public void init() {
client = new MongoClient("192.168.203.149", 27017);
}
//连接数据库
@Test
public void connectDB() {
MongoDatabase database = client.getDatabase("kkb");
System.out.println(database.getName());
}
//新建collection
@Test
public void createCollection() {
MongoDatabase database = client.getDatabase("kkb");
database.createCollection("mycollection2");
}
//查询collection
@Test
public void getCollection() {
MongoDatabase database = client.getDatabase("kkb");
MongoCollection<Document> collection = database.getCollection("mycollection");
MongoIterable<String> collectionNames = database.listCollectionNames();
for (String string : collectionNames) {
System.out.println("collection name : " + string);
}
}
//插入数据
@Test
public void insertDocument() {
MongoDatabase database = client.getDatabase("kkb");
MongoCollection<Document> collection = database.getCollection("mycollection2");
Document document = new Document("name", "James");
document.append("age", 34);
document.append("sex", "男");
Document document2 = new Document("name", "wade");
document2.append("age", 36);
document2.append("sex", "男");
Document document3 = new Document("name", "cp3");
document3.append("age", 32);
document3.append("sex", "男");
List<Document> documents = new ArrayList<>();
documents.add(document);
documents.add(document2);
documents.add(document3);
collection.insertMany(documents);
System.out.println("文档插入成功");
}
//搜索数据
@Test
public void findDocuments() {
MongoDatabase database = client.getDatabase("kkb");
System.out.println("connect successful");
MongoCollection<Document> collection = database.getCollection("mycollection2");
System.out.println("获取集合成功:" + collection.getNamespace());
FindIterable<Document> iterable = collection.find();
for (Document document : iterable) {
System.out.println(document.toJson());
}
}
//更新数据
@Test
public void updateDocuments() {
MongoDatabase database = client.getDatabase("kkb");
System.out.println("connect successful");
MongoCollection<Document> collection = database.getCollection("mycollection");
System.out.println("获取集合成功:" + collection.getNamespace());
collection.updateMany(Filters.eq("age", 18), new Document("$set", new Document("age", 20)));
FindIterable<Document> iterable = collection.find();
for (Document document : iterable) {
System.out.println(document.toJson());
}
}
//删除数据
@Test
public void deleteDocuments() {
MongoDatabase database = client.getDatabase("kkb");
System.out.println("connect successful");
MongoCollection<Document> collection = database.getCollection("mycollection");
System.out.println("获取集合成功:" + collection.getNamespace());
// 删除符合条件的第一个文档
collection.deleteOne(Filters.eq("age", 20));
collection.deleteOne(Filters.eq("name", "James"));
// 删除符合条件的所有文档
collection.deleteMany(Filters.eq("age", 20));
FindIterable<Document> iterable = collection.find();
for (Document document : iterable) {
System.out.println(document.toJson());
}
}
}
四、MongoDB Java客户端——Spring Data MongoDB
(一)pom文件配置
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
(二)Spring配置文件spring-mongodb.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xmlns:repository="http://www.springframework.org/schema/data/repository"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
http://www.springframework.org/schema/data/repository
http://www.springframework.org/schema/data/repository/spring-repository.xsd">
<!-- 加载mongodb的配置属性文件 -->
<context:property-placeholder location="classpath:mongodb.properties" />
<!-- 扫描持久层 -->
<context:component-scan base-package="com.kkb.mongodb.springdata" />
<!-- 配置mongodb客户端连接服务器的相关信息 -->
<mongo:mongo-client host="${mongo.host}" port="${mongo.port}" id="mongo">
<mongo:client-options
write-concern="${mongo.writeconcern}"
connect-timeout="${mongo.connectTimeout}"
socket-keep-alive="${mongo.socketKeepAlive}" />
</mongo:mongo-client>
<!-- mongo:db-factory dbname="database" mongo-ref="mongo" / -->
<!--这里的dbname就是自己的数据库/collection的名字 -->
<mongo:db-factory id="mongoDbFactory" dbname="kkb" mongo-ref="mongo" />
<!-- 配置mongodb的模板类:MongoTemplate -->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>
</beans>
(三)Java测试类
package com.kkb.mongodb.springdata.test;
import java.util.List;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.kkb.mongodb.springdata.dao.UserDao;
import com.kkb.mongodb.springdata.po.User;
import com.mongodb.client.result.UpdateResult;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-mongodb.xml")
public class SpringDataMongodbTest {
@Resource
private UserDao userDao;
@Test
public void test1() {
User user = new User();
user.setName("科比");
user.setAge(26);
userDao.save(user);
User user2 = new User();
user2.setName("詹姆斯");
user2.setAge(33);
userDao.save(user2);
User user3 = new User();
user3.setName("韦德");
user3.setAge(36);
userDao.save(user3);
User user4 = new User();
user4.setName("罗斯");
user4.setAge(30);
userDao.save(user4);
System.out.println("插入成功!");
}
@Test
public void test2() {
Query query = new Query(Criteria.where("name").is("科比"));
List<User> list = userDao.find(query);
for (User user : list) {
System.out.println(user);
}
System.out.println("=======================");
List<User> list2 = userDao.find(new Query());
for (User user : list2) {
System.out.println(user);
}
System.out.println("=======================");
User user = (User) userDao.findOne(query);
System.out.println(user);
}
@Test
public void test3() {
Query query = new Query(Criteria.where("name").is("韦德"));
Update update = new Update();
update.set("sex", "纯爷们");
UpdateResult updateResult = userDao.update(query, update);
System.out.println(updateResult.getUpsertedId());
}
@Test
public void test4() {
List<User> findAll = userDao.findAll("user");
for (User user : findAll) {
System.out.println(user);
}
}
@Test
public void test5() {
Query query = new Query();
long count = userDao.count(query,"user");
System.out.println("总条数:" + count);
}
@Test
public void test6() {
Query query = new Query(Criteria.where("name").is("科比"));
userDao.remove(query);
}
}
eResult updateResult = userDao.update(query, update);
System.out.println(updateResult.getUpsertedId());
}
@Test
public void test4() {
List<User> findAll = userDao.findAll("user");
for (User user : findAll) {
System.out.println(user);
}
}
@Test
public void test5() {
Query query = new Query();
long count = userDao.count(query,"user");
System.out.println("总条数:" + count);
}
@Test
public void test6() {
Query query = new Query(Criteria.where("name").is("科比"));
userDao.remove(query);
}
}