MongoDB和Redis都是属于NOSQL数据库,NOSQL,就是Not Only SQL的意思。
Redis:键值对数据库
MongoDB:文档数据库,所谓文档是一种类似JSON的结构(BJSON)用于存储程序运行过程中产生的数据。MongoDB偶数版本是稳定版
一、安装
1、下载并安装
官网:https://www.mongodb.com/download-center/community
2、配置环境变量 path
D:\Program Files\MongoDB\Server\4.2\bin
3、命令行输入 mongod 验证环境变量是否配置正确;
4、在c盘根目录创建一个文件夹 data,在data中创建一个文件夹db;
5、启动服务端
cmd命令行输入mongod 启动数据库,默认用的是C:\data\db作为数据库,
mongod --dbpath D:\data\db 【--port 10086】 带--dbpath参数启动数据库,并将"D:\data\db"目录设置为数据库,
参数--port将默认端口27017更换成别的端口号;
6、启动客户端
另外打开一个cmd窗口,输入mongo连接mongoDB数据库,当出现>,即代表启动成功。
7、将MongoDB设置为系统服务,可以自动在后台启动,不需要每次都手动启动(非必要):
1、在c盘根目录创建一个文件夹 data,在data中创建文件夹db和log;
2、在安装目录(D:\Program Files\MongoDB\Server\4.2\bin)下添加配置文件mogod.cfg
二、MongoDB基本概念
SQL术语/概念 MongoDB术语/概念 解释/说明
database database 数据库 仓库
table collection 数据库表/集合,集合类似数组,在集合中可以存放文档
row document 数据记录行/文档,文档是数据库的最小单位,存储和操作的内容都是文档
column field 数据字段/域
index index 索引
table joins 表连接,MongoDB不支持
primary key primary key 主键,MongoDB自动将_id字段设置为主键
基本指令:
show dbs/show database --显示当前存在的所有数据库
use DATABASE_NAME --如果数据库不存在,则创建数据库,否则切换到指定数据库。
db.dropDatabase() --删除当前数据库
db --显示当前所处的数据库
show collections --显示数据库中所有的集合
db.collection.drop() --删除集合,如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。
db.createCollection(name, options) --创建集合,name: 要创建的集合名称,options: 可选参数, 指定有关内存大小及索引的选项
三、数据库CRUD操作
新增插入:
db.COLLECTION_NAME.insert(document)
-- 若插入的数据主键已经存在,则会抛 org.springframework.dao.DuplicateKeyException 异常,提示主键重复,不保存当前数据。
db.COLLECTION_NAME.save({name:"meng", age:25, gender:"女"})
-- 如果 _id 主键存在则更新数据,如果不存在就插入数据。该方法新版本中已废弃,可以使用 db.collection.insertOne() 或 db.collection.replaceOne() 来代替。
3.2 版本后还有以下几种语法可用于插入文档:
db.collection.insertOne({}):向指定集合中插入一条文档数据
db.collection.insertMany([]):向指定集合中插入多条文档数据
当我们创建文档时,如果文档所在的集合或者数据库不存在,则会自动创建数据库和集合。
更新文档:
1、update()默认用一个对象更新另一个对象,若只想更新指定属性,则需用$set操作符;
删除指定属性,用$unset操作符;
update(),默认只会修改一个,如需要修改多个,需要将参数multi置为true;
updateOne()修改一个,updateMany()修改多个
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
参数说明:
query : update的查询条件,类似sql update查询内where后面的。
update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
writeConcern :可选,抛出异常的级别。
eg:
db.col.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}})
2、save() 方法通过传入的文档来替换已有文档,_id 主键存在就更新,不存在就插入。
3、db.col.replaceOne({},{}) --替换
4、内嵌文档更新
数组操作:$push --向数组中插入一个新元素
$pop --从数组中移除一个元素
$addToSet --向数组中插入一个新元素,如果数组中已存在该元素,则不添加
删除:
remove() 方法:默认删除满足条件的所有文档,若需只删一个,则第二个参数传true
db.collection.remove(
<query>,
<justOne>
)
如删除集合下全部文档:db.collection.deleteMany({}),db.collection.drop() --删除集合
删除 status 等于 A 的全部文档:db.collection.deleteMany({ status : "A" })
删除 status 等于 D 的一个文档:db.collection.deleteOne( { status: "D" } )
db.collection.drop() --删除集合
db.dropDatabase() --删除数据库
查询:
db.collection.find(query, projection)
query :可选,使用查询操作符指定查询条件
projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
eg:
db.col.find({key1:value1, key2:value2}, {key1:1, key2:1}).pretty()
统计总数:
db.collection.find(query, projection).count()
还可支持内嵌文档(文档中的键对应的值仍旧是文档)查询
AND 和 OR 联合使用:
MongoDB 的 find() 方法可以传入多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件。
MongoDB OR 条件语句使用了关键字 $or,
语法:db.col.find({$or: [{key1: value1}, {key2:value2}]})
AND 和 OR 联合使用:
db.col.find({"price": {$gt:50}, $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]})
like模糊查询:
模糊查询可以使用$regex操作符或直接使用正则表达式对象。MongoDB使用$regex操作符来设置匹配字符串的正则表达式
db.col.find( {key: {$regex:/value/}}) 或者 db.col.find( {key:/value/}) -- %value%,包含某字段的模糊查询
db.col.find({"key":{$regex:/^value/}}) -- 查询以某字段为开头的文档
db.col.find({"key":{$regex:/value^/}}) -- 查询以某字段为结尾的文档
db.col.find({"key":{$regex:/value/i}}) -- 查询忽略大小写
$type操作符:
db.col.find({"title" : {$type : 2}}) --获取 "col" 集合中 title 为 String 的数据
或
db.col.find({"title" : {$type : 'string'}})
limit和skip方法(分页):
skip()从第几个开始读,limit()读几个,skip()方法默认参数为 0,没有指定limit()方法中的参数则显示集合中的所有数据。
db.COLLECTION_NAME.find().limit(NUMBER) --读取指定数量的数据记录
db.COLLECTION_NAME.find().skip(NUMBER).limit(NUMBER) --使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。
sort() 排序方法,first(),last():
db.COLLECTION_NAME.find().sort({KEY:1}) --sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
skip(), limilt(), sort()三个放在一起执行的时候,
执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit()。
$all,$in
聚合的方法使用aggregate():
db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}]) -- 相当于mysql中的 select by_user, count(*) from mycol group by by_user
表达式 描述 实例
$sum 计算总和。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$key"}}}])
$avg 计算平均值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$key"}}}])
$min 获取集合中所有文档对应值得最小值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$key"}}}])
$max 获取集合中所有文档对应值得最大值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$key"}}}])
$push 将值加入一个数组中,不会判断是否有重复的值。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSet 将值加入一个数组中,会判断是否有重复的值,若相同的值在数组中已经存在了,则不加入。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
$first 根据资源文档的排序获取第一个文档数据。 db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$last 根据资源文档的排序获取最后一个文档数据 db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])
创建索引:
db.users.ensureIndex({gender:1,user_name:1})
hint():
可以使用 hint 来强制 MongoDB 使用一个指定的索引。
explain()查询分析:
db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1}).explain()
四、Java连接MongoDB(MongoDB JDBC 驱动)
MongoDB数据库,一般情况下,只需要连接一次,连接一次以后,除非服务停止服务器关闭,否则连接一般不会断开
使用:
// 连接到 mongodb 服务
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
// 连接到数据库
MongoDatabase mongoDatabase = mongoClient.getDatabase("mycol");
System.out.println("Connect to database successfully");
MongoCollection<Document> collection = mongoDatabase.getCollection("test");
System.out.println("集合 test 选择成功");
//插入文档
/**
* 1. 创建文档 org.bson.Document 参数为key-value的格式
* 2. 创建文档集合List<Document>
* 3. 将文档集合插入数据库集合中 mongoCollection.insertMany(List<Document>) 插入单个文档可以用 mongoCollection.insertOne(Document)
* */
Document document = new Document("title", "MongoDB").
append("description", "database").
append("likes", 100).
append("by", "Fly");
List<Document> documents = new ArrayList<Document>();
documents.add(document);
collection.insertMany(documents);
/**
* 1. 获取迭代器FindIterable<Document>
* 2. 获取游标MongoCursor<Document>
* 3. 通过游标遍历检索出的文档集合
* */
FindIterable<Document> findIterable = collection.find();
MongoCursor<Document> mongoCursor = findIterable.iterator();
while(mongoCursor.hasNext()){
System.out.println(mongoCursor.next());
}
//更新文档 将文档中likes=100的文档修改为likes=200
collection.updateMany(Filters.eq("likes", 100), new Document("$set",new Document("likes",200)));
//检索查看结果
FindIterable<Document> findIterable = collection.find();
MongoCursor<Document> mongoCursor = findIterable.iterator();
while(mongoCursor.hasNext()){
System.out.println(mongoCursor.next());
}
//删除符合条件的第一个文档
collection.deleteOne(Filters.eq("likes", 200));
//删除所有符合条件的文档
collection.deleteMany (Filters.eq("likes", 200));
//检索查看结果
FindIterable<Document> findIterable = collection.find();
MongoCursor<Document> mongoCursor = findIterable.iterator();
while(mongoCursor.hasNext()){
System.out.println(mongoCursor.next());
}