wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-6.0.5.tgz
tar -zxvf mongodb-linux-x86_64-rhel70-6.0.5.tgz
mv mongodb-linux-x86_64-rhel70-6.0.5 mongodb-6.0.5
cd mongodb-6.0.5
mkdir data
mkdir log
mkdir conf
bin/mongod --port=27017 --dbpath=/usr/local/mongo/mongodb-6.0.5/data --logpath=/usr/local/mongo/mongodb-6.0.5/log/mongodb.log \--bind_ip=0.0.0.0 --fork
export MONGODB_HOME=/usr/local/mongo/mongodb-6.0.5
PATH=$PATH:$MONGODB_HOME/bin
cd conf
vim mongo.conf
配置文件的内容为
systemLog:
destination: file
path: /usr/local/mongo/mongodb-6.0.5/log/mongod.log
logAppend: true
storage:
dbPath: /usr/local/mongo/mongodb-6.0.5/data
engine: wiredTiger #存储引擎
journal:
enabled: true
net:
bindIp: 0.0.0.0
port: 27017
processManagement:
fork: true
#启动mongodb
mongod -f /usr/local/mongo/mongodb-6.0.5/conf/mongo.conf
#关闭mongodb
mongod --port=27017 --dbpath=/usr/local/mongo/mongodb-6.0.5/data --shutdown
#centos7 安装
mongosh wget https://downloads.mongodb.com/compass/mongodb-mongosh-1.8.0.x86_64.rpm
yum install -y mongodb-mongosh-1.8.0.x86_64.rpm
# 连接mongodb server端
mongosh --host=192.168.2.66 --port=27017
mongosh 192.168.2.66:27017
# 指定uri方式连接
mongosh mongodb://192.168.2.66:27017/test
#查看所有数据库
show dbs
#切换到指定数据库,不存在则创建
use users
#删除当前数据库
db.dropDatabase()
# 查看集合
show collections
#创建集合
db.createCollection("emp")
#删除集合
db.emp.drop()
#设置管理员用户名需要切换到admin
use admin
#创建管理员
db.createUser({user:"fox",pwd:"fox",roles:["root"]})
#查看当前数据库所有用户信息
show users
#显示可设置权限
show roles
#显示所用用户
db.system.users.find()
#创建用户
db.createUser({user:"fox",pwd:"fox",roles:["root"]})
#重新赋予用户相关权限
db.grantRolesToUser("fox",[{role:"clusterAdmin",db:"admin"},{role:"userAdminAnyDatabase",db:"admin"},{role:"readWriteAnyDatabase",db:"admin"}])
#进入权限库
use admin
#删除某个用户
db.dropUser("fox")
#删除当前所有用户
db.dropAllUser()
use appdb
db.createUser({user:"appdb",pwd:"nickel",roles:["dbOwner"]})
#启用鉴权
mongod -f /usr/local/mongo/mongodb-6.0.5/conf/mongo.conf --aut
#登录数据库
mongosh 192.168.2.66 -u nickel -p nickel --authenticationDatabase=admin
#拉取mongo镜像
docker pull mongo:6.0.5
#运行mongo镜像
docker run --name mongo-server -p 29017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=fox \
-e MONGO_INITDB_ROOT_PASSWORD=fox \
-d mongo:6.0.5 --wiredTigerCacheSizeGB 1
mongosh ip:29017 -u nickel -p nickel
1.GUI工具
官方GUI:COMPASS
MongoDB图形化管理工具(GUI),能够帮助您在不需要知道MongoDB查询语法的前提下,便利地分析和理解您的数据库模式,并且帮助您可视化地构建查询。
下载地址:https://www.mongodb.com/zh-cn/products/compass
2.Robo 3T(免费)*
下载地址:https://robomongo.org/
3.Studio 3T(收费,试用30天)
下载地址:https://studio3t.com/download/
*4.MongoDB Database Tools
下载地址:https://www.mongodb.com/try/download/database-tools
文件名称作用mongostat数据库性能监控工具mongotop热点表监控工具mongodump数据库逻辑备份工具mongorestore数据库逻辑恢复工具mongoexport数据导出工具mongoimport数据导入工具bsondumpBSON格式转换工具mongofilesGridFS文件工具
db.emps.insertOne({name:'fox',age:35})
db.emps.insertMany([{name:'小明',age:5},{name:'小红',age:10}])
var tags=["nosql","mongodb","document","developer","popular"];
var types=["technology","sociality","travel","novel","literature"];
var books=[];
for(var i=0;i<50;i++){
var typeIdx=Math.floor(Math.random()*types.length);
var tagIdx=Math.floor(Math.random()*tags.length);
var favCount=Math.floor(Math.random()*100);
var book={
title:"book-"+i,
type:types[typeIdx],
tag:tags[tagIdx],
favCount:favCount,
author:"xxx"+i
};
books.push(book)
}
db.books.insertMany(books);
#创建文件夹
mkdir file
#进入文件夹
cd file
#创建books.js文件
vim books.js
#连接mongodb数据库
mongosh -u nickel -p nickel
#切换到相关的库
use books
#执行js文件
load("books.js")
#单条查询
db.books.findOne()
#多条查询
db.books.find()
#条件查询(查询tag=nosql 只显现title和author两个字段,其余默认)
db.books.find({tag:"nosql"},{title:1,author:1})
#条件查询(tag=nosql 只显现title和author两个字段,其余不显示)
db.books.find({tag:"nosql"},{_id:0,title:1,author:1})
#条件查询(按照ID查询一条数据)
db.books.find({_id:ObjectId("6568a247d664d21d99dcbbbe")})
#条件查询(type=travel和favCount>60)
db.books.find({type:'travel',favCount:{$gt:60}})
#查询条件中使用正则表达式(type中包含so的数据)
#方式1
db.books.find({type:{$regex:"so"}})
#方式2
db.books.find({type:/so/})
#按照favCount进行倒序(type="travel")
db.books.find({type:"travel"}).sort({favCount:-1})
#按照favCount进行正序(type="travel")
db.books.find({type:"travel"}).sort({favCount:1})
#查询16条记录后三条记录
db.books.find().skip(16).limit(3)
#查询第一页的数据
db.books.find({}).sort({_id:1}).limit(10)
#查询第二页的数据
#db.books.find({_id: {$gt: <第一页最后一个_id>}}).sort({_id: 1}).limit(10);
db.books.find({_id:{$gt:ObjectId("65691cb29b6f2f9eb3ffd693")}}).sort({_id:1}).limit(10)
#查询第三页的数据
#db.books.find({_id: {$gt: <第二页最后一个_id>}}).sort({_id: 1}).limit(10)
db.books.find({_id:{$gt:ObjectId("65691cb29b6f2f9eb3ffd69d")}}).sort({_id:1}).limit(10)
db.coll.find({x: 100}).limit(50);
db.coll.count({x: 100});
#修改数据(name=小明 age从5修改为8)
db.emps.updateOne({name:"小明"},{$set:{age:8}})
#修改数据(name=小明 把age增加为1)
db.emps.updateOne({name:"小明"},{$inc:{age:1}})
#更改列名(name=小明 把name改为name1)
db.emps.updateOne({name:"小明"},{$rename:{"name":"name1"}})
#增加列名(增加sex列名,默认为1)
db.emps.updateMany({},{$unset:{"sex":1}})
#删除列名(删除sex列名)
db.emps.updateMany({},{$unset:{"sex":1}})
#不存在则插入(插入title=my book)
db.books.updateOne({title:"my book"},{$set:{tags:["nodql","mongodb"],type:"none",author:"fox"}},{upsert:true})
#更新多条数据(更新type="novel",增加publishedDate字段)
db.books.updateMany({type:"novel"},{$set:{publishedDate:new Date()}})
#查询数据并修改数据,显示的数据是修改之前的数据
db.books.findAndModify({
query:{_id:ObjectId("65691cb29b6f2f9eb3ffd6ac")},
update:{$inc:{favCount:1}}
})
#查询数据并修改数据,显示的数据是修改之后的数据
db.books.findAndModify({
query:{_id:ObjectId("65691cb29b6f2f9eb3ffd6ac")},
update:{$inc:{favCount:1}},
new:true
})
#删除满足条件((type=novel))的id最小的数据
db.books.deleteOne({type:"novel"})
#删除集合下的全部文档
db.books.deleteMany({})
#删除满足条件((type=novel))所有数据
db.books.deleteMany({type:"novel"})
#删除满足条件((type=novel))一条数据,并显示该条删除的数据
db.books.findOneAndDelete({type:"novel"})
#按照favCount正序之后,然后删除第一条数据
db.books.findOneAndDelete({type:"novel"},{sort:{favCount:1}})
#批量插入数据
db.pizzas.insertMany( [
{ _id: 0, type: "pepperoni", size: "small", price: 4 },
{ _id: 1, type: "cheese", size: "medium", price: 7 },
{ _id: 2, type: "vegan", size: "large", price: 8 }
] )
#批量操作数据
db.pizzas.bulkWrite([
{insertOne:{document:{_id:3,type:"beef",size:"medium",price:6}}},
{insertOne:{ducument:{_id:4,type:"sausage",size:"large",price:10}}},
{updateOne:{
filter:{type:"cheese"},
update:{$set:{price:8}}
}},
{deleteOne:{filter:{type:"pepperoni"}}},
{replaceOne:{
filter:{type:"vegan"},
replacement:{type:"tofu",size:"small",price:4}
}}
])
#插入时间格式
db.dates.insertMany([
{data1:Date()},{data2:new Date()},{data3:ISODate()}
])
#插入嵌套文档
db.books.insert({
title:"我们的爱情故事",
author:{
name:"Nickel",
gender:"男",
hometown:"重庆"
}
})
#按照嵌套文档的内容进行查找
db.books.find({"author.name":"Nickel"})
#修改嵌套文档中name=Nickel的hometownm名称
db.books.updateOne({"author.name":"Nickel"},{$set:{"author.hometown":"重庆/贵州"}})
#增加tags标签字段
db.books.updateOne({"author.name":"Nickel"},{$set:{"tags:["履行","随笔","散文","爱情","文学"]"}})
#在tags标签里面追加单个标签
db.books.updateOne({"author.name":"Nickel"},{$push:{tags:"猎奇"}})
#在tags标签里面追加多个标签
db.books.updateOne({"author.name":"Nickel"},{$push:{tags:{$each:["伤感","想象力"]}}})
#在tags标签里面追加多个标签,然后截取后面三个标签
db.books.updateOne({"author.name":"Nickel"},{$push:{tags:{$each:["伤感","想象力"],$slice:-3}}})
#嵌套数组的运用
db.goods.insertMany([
{
name:"羽绒服",
tags:[
{tagKey:"size",tagValue:["M","L","XL","XXL","XXXL"]},
{tagKey:"color",tagValue:["黑色","宝蓝"]},
{tagKey:"style",tagValue:"韩风"},
]
},
{
name:"羊毛衫",
tags:[
{tagKey:"size",tagValue:["L","XL","XXL"]},
{tagKey:"color",tagValue:["蓝色","否色"]},
{tagKey:"style",tagValue:"韩风"},
]
}
])
#筛选出黑色的数据
db.goods.find({
tags:{$elemMatch:{tagKey:"color",tagValue:"黑色"}}
})
#筛选出color=蓝色,并且size=XL的商品
db.goods.find({
tags:{
$all:[
{$elemMatch:{tagKey:"color",tagValue:"黑色"}},
{$elemMatch:{tagKey:"size",tagValue:"XL"}}
]
}
})
固定集合(capped collection)是一种限定大小的集合,其中capped是覆盖、限额的意思。跟普通的集合相比,数据在写入这种集合时遵循FIFO原则。可以将这种集合想象为一个环状的队列,新文档在写入时会被插入队列的末尾,如果队列已满,那么之前的文档就会被新写入的文档所覆盖。通过固定集合的大小,我们可以保证数据库只会存储“限额”的数据,超过该限额的旧数据都会被丢弃。
db.createCollection(“logs”,{capped:true,size:4096,max:10})
#创建固定集合
db.createCollection("logs",{capped:true,size:4096,max:10})
#将普通集合转化为固定集合
db.runCommand({"convertToCapped": "mycoll", size: 100000})
#参事向集合中插入数据,查看是否覆盖
for(var i=5;i<15;i++){
db.logs.insert({t:"row"+i})
}
适用场景
&emsp固定集合很适合用来存储一些“临时态”的数据。“临时态”意味着数据在一定程度上可以被丢弃。同时,用户还应该更关注最新的数据,随着时间的推移,数据的重要性逐渐降低,直至被淘汰处理。
一些适用的场景如下:
股票监听案例
db.createCollection("gupiao_queue",{capped:true,size:10485760})
db.gupiao_queue.createIndex({timestamped:1})
function pushEvent(){
while(true){
db.gupiao_queue.insert({
timestamped:new Date(),
stock: "MongoDB Inc",
price: 100*Math.random(1000)
});
print("publish stock changed");
sleep(1000);
}
}
pushEvent()
function listen(){
var cursor = db.gupiao_queue.find({timestamped:{$gte:new Date()}}).tailable();
while(true){
if(cursor.hasNext()){
print(JSON.stringify(cursor.next(),null,2));
}
sleep(1000);
}
}
listen()
MongoDB为什么会使用BSON?
JSON是当今非常通用的一种跨语言Web数据交互格式,属于ECMAScript标准规范的一个子集。JSON(JavaScript Object Notation, JS对象简谱)即JavaScript对象表示法,它是JavaScript对象的一种文本表现形式。
作为一种轻量级的数据交换格式,JSON的可读性非常好,而且非常便于系统生成和解析,这些优势也让它逐渐取代了XML标准在Web领域的地位,当今许多流行的Web应用开发框架,如SpringBoot都选择了JSON作为默认的数据编/解码格式。
JSON只定义了6种数据类型:
MongoDB集合中所有的文档都有一个唯一的_id字段,作为集合的主键。在默认情况下,_id字段使用ObjectId类型,采用16进制编码形式,共12个字节。
为了避免文档的_id字段出现重复,ObjectId被定义为3个部分:
org.springframework.boot
spring-boot-starter-data-mongodb
org.projectlombok
lombok
1.18.16
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
spring:
data:
mongodb:
uri: mongodb://nickel:[email protected]:27017/test?authSource=admin
package com.nq.springbootmongodb.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import java.util.Date;
/**
* @Auther: Nickel
* DATE: 2023/12/2 14:56
* Description:
* @Version 1.0
*/
@Document("emp")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
@Id
private Integer id;
@Field("username")
private String name;
@Field
private int age;
@Field
private Double salary;
@Field
private Date entryDay;
}
/**
* @Auther: Nickel
* DATE: 2023/12/2 14:40
* Description:
* @Version 1.0
*/
@SpringBootTest
public class TestCollection {
@Autowired
MongoTemplate mongoTemplate;
@Test
public void test1(){
boolean exists = mongoTemplate.collectionExists("emp");
if(exists){
//删除集合
mongoTemplate.dropCollection("emp");
}
mongoTemplate.createCollection("emp");
}
}
@Test
public void testInsert(){
Employee employee=new Employee(1,"Nickel",28,3000d,new Date());
mongoTemplate.insert(employee);
List<Employee> list = Arrays.asList(
new Employee(2, "fox", 22, 280020d, new Date()),
new Employee(3, "zhuge", 33, 2263d, new Date()),
new Employee(4, "zhouyu", 35, 282320d, new Date())
);
mongoTemplate.insert(list,Employee.class);
}
@Test
public void testFind(){
//查询所有文档
System.out.println("========查询所有文档======");
List<Employee> list = mongoTemplate.findAll(Employee.class);
list.forEach(System.out::println);
//根据ID进行查询
System.out.println("======根据ID进行查询========");
Employee employee = mongoTemplate.findById(1, Employee.class);
System.out.println(employee);
//返回第一个文档的数据
System.out.println("=======返回第一个文档的数据=======");
Employee one = mongoTemplate.findOne(new Query(), Employee.class);
System.out.println(one);
//条件查询
System.out.println("=======查询薪资大于等于8000的员工=======");
//查询薪资大于等于8000的员工
Query query8000=new Query(Criteria.where("salary").gte(8000));
List<Employee> list2 = mongoTemplate.find(query8000, Employee.class);
list2.forEach(System.out::println);
System.out.println("=======查询薪资大于等于4000小于等于10000=======");
//查询薪资大于等于4000小于等于10000
Query query8_10=new Query(Criteria.where("salary").gte(4000).lte(10000));
List<Employee> list3 = mongoTemplate.find(query8_10, Employee.class);
list3.forEach(System.out::println);
System.out.println("=======模糊查询name中包含zh的=======");
//正则模糊查询 java正则不需要有//
Query query_zh=new Query(Criteria.where("name").regex("zh"));
List<Employee> list4 = mongoTemplate.find(query_zh, Employee.class);
list4.forEach(System.out::println);
//and or 多条件查询
System.out.println("=======查询年龄大于25薪资大于8000的员工=======");
Criteria criteria_25_8000=new Criteria();
//查询年龄大于25薪资大于8000的员工
criteria_25_8000.andOperator(Criteria.where("age").gte(25),Criteria.where("salary").gte(8000));
Query query=new Query(criteria_25_8000);
List<Employee> list5 = mongoTemplate.find(query, Employee.class);
list5.forEach(System.out::println);
System.out.println("=======查询年龄大于25薪资大于8000的员工=======");
Criteria criteria_zhuge_8000=new Criteria();
//查询姓名是zhuge或者薪资大于8000的员工
criteria_zhuge_8000.orOperator(Criteria.where("name").is("zhuge"),Criteria.where("salary").gte(8000));
Query query1=new Query(criteria_zhuge_8000);
List<Employee> list6 = mongoTemplate.find(query1, Employee.class);
list6.forEach(System.out::println);
//排序
System.out.println("=======排序=======");
Query query2=new Query(criteria_zhuge_8000).with(Sort.by(Sort.Order.desc("salary")));
List<Employee> list7 = mongoTemplate.find(query2, Employee.class);
list7.forEach(System.out::println);
//分页
System.out.println("=======分页=======");
query=new Query().skip(2) //跳过前面两条
.limit(1); //显示一条数据
List<Employee> list8 = mongoTemplate.find(query, Employee.class);
list8.forEach(System.out::println);
}
@Test
public void testFindByJson(){
System.out.println("=======分页=======");
//查询年龄大于25或者薪资大于等于8000
String json="{$or:[" +
"{age:{$gt:25}}" +
",{salary:{$gte:8000}}" +
"]}";
Query query=new BasicQuery(json);
List<Employee> list = mongoTemplate.find(query,Employee.class);
list.forEach(System.out::println);
}
@Test
public void testUpdate(){
Query query=new Query(Criteria.where("salary").lte(5000));
System.out.println("=======更新前=======");
List<Employee> list = mongoTemplate.find(query, Employee.class);
list.forEach(System.out::println);
System.out.println("=======把id为1的薪资调为5000=======");
//把id为1的薪资调为5000
Update update=new Update();
update.set("salary",5000);
System.out.println("=======更新满足条件的一条======");
UpdateResult updateResult = mongoTemplate.updateFirst(query, update, Employee.class);
System.out.println("=======更新满足条件的所有记录=====");
UpdateResult updateResult2 = mongoTemplate.updateMulti(query, update, Employee.class);
List<Employee> list2 = mongoTemplate.find(query, Employee.class);
list2.forEach(System.out::println);
}
@Test
public void testDelete(){
//删除所有文档
// mongoTemplate.remove(new Query(),Employee.class);
System.out.println("=======删除前=======");
List<Employee> list = mongoTemplate.find(new Query(), Employee.class);
list.forEach(System.out::println);
System.out.println("=======删除薪资大于等于1000=======");
//删除薪资大于等于1000
Query query2=new Query(Criteria.where("salary").gte(10000));
mongoTemplate.remove(query2,Employee.class);
List<Employee> list2 = mongoTemplate.find(new Query(), Employee.class);
list2.forEach(System.out::println);
}