概念
1.MongoDB 是一个文档数据库,数据以 BSON 方式存储(类似于json)
2.文档(Document):类似于mysql的一行数据
3.集合(Collection):类似于mysql的一张表
4.数据库(Database):一个数据库中可以有多个集合
5.主键,MongoDB自动将“_id”字段设置为主键,id会自动生成
6.不支持表连接(join)
7.MongoDB的文档不能有重复的键
8.文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
9.以下划线""开头的键是保留的(不是严格要求的)。
10.常用数据类型(不止这些):
String 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。
Integer 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。
Boolean 布尔值。用于存储布尔值(真/假)。
Double 双精度浮点值。用于存储浮点值。
Object 用于内嵌文档。
Null 用于创建空值。
Date 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。
操作数据库语法
数据库及文档操作
# 展示当前使用数据库
db
# 整个mongo状态
db.stats();
# 指定使用数据库,随后如果想这个库中插入入数据则会创建
use test
# 随便指定一个集合名称并插入一条数据便会创建集合并插入
db.a.insert({
name: "zs"
})// 新建一个test库,库中新建一个a集合,集合中插入一条数据
文档操作
# 新增一个
db.collection.insertOne({
name: "John",
age: 30
})
# 新增多个
db.collection.insertMany([
{name: "Alice", age: 25},
{name: "Bob", age: 28}
])
# 删一个
db.collection.deleteOne({name: "John"})
# 删多个
db.collection.deleteMany({age: {$lt: 30}})
# 修改一个
db.collection.updateOne(
{name: "John"}, // 查询条件
{$set: {age: 31}}, // 更新操作
{upsert: true} // 如果文档不存在,则插入新文档
)
# 修改多个
db.collection.updateMany(
{name: "John"}, // 查询条件
{$set: {age: 31}}, // 更新操作
{upsert: true} // 如果文档不存在,则插入新文档
)
# 查
// 查所有
db.a.find()
// 条件查询
// && 查询name=123并且age=18的文档
db.a.find({name : "fs", age : 18})
// != username不为joe的文档
db.a.find({"username" : {"$ne" : "joe"}})
// or ticket_no为725或winner为true
db.users.find({"$or" : [{"ticket_no" : 725}, {"winner" : true}]})
//指定返回字段
// name为fs,但只返回name和age字段
db.a.find({name : "fs"}, {"name" : 1, "age" : 1})
// name为fs,但不返回name和age字段
db.a.find({name : "fs"}, {name : 0, age : 0})
// in / not in
//ticket_no值为725, 542, 390
db.a.find({"ticket_no" : {"$in" : [725, 542, 390]}})
//ticket_no值不为725, 542, 390
db.a.find({"ticket_no" : {"$nin" : [725, 542, 390]}})
// id_num除以 5 的余数等于 1 的文档
db.users.find({"id_num" : {"$mod" : [5, 1]}}) select * from users where (id_num mod 5) = 1
// not age 不等于27
db.users.find({"$not": {"age" : 27}})
// username = null 且 文档中存在username字段
db.users.find({"username" : {"$in" : [null], "$exists" : true}})
// object
//嵌套查询 name对象的first为Joe,name对象的last为Schmoe
db.people.find({ "name.first": "Joe", "name.": "Schmoe" })
// array
// 对数组的查询, 字段fruit中,既包含"apple",又包含"banana"的纪录
db.food.find({fruit : {$all : ["apple", "banana"]}})
// 对数组的查询, 查询数组元素个数是3的记录,$size前面无法和其他的操作符复合使用
db.food.find({"fruit" : {"$size" : 3}})
//文档的 comments 数组中必须包含至少一个子文档,该子文档满足:author 为 "joe"。score 大于等于 5。
db.blog.find({
"comments": {
"$elemMatch": {
"author": "joe",
"score": { "$gte": 5 }
}
}
})
//按x升序排,-1则降序,获取排序后的第 11 条记录(基于 0 索引,即跳过前 10 条记录后获取第 1 条记录)。
db.foo.find().sort({"x" : 1}).limit(1).skip(10);
//分组
db.sales.aggregate([
{
$group: {
_id: "$category",
count: { $sum: 1 }, // 商品数量
totalPrice: { $sum: "$price" }, // 总价格
avgPrice: { $avg: "$price" }, // 平均价格
maxPrice: { $max: "$price" } // 最高价格
}
}
])
// 分组返回结果
[
{
"_id": "electronics",
"count": 3,
"totalPrice": 450,
"avgPrice": 150,
"maxPrice": 200
},
{
"_id": "clothing",
"count": 2,
"totalPrice": 130,
"avgPrice": 65,
"maxPrice": 80
}
]
整合springboot的MongoTemplate用法
springboot配置
引入maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
// yml配置
spring:
data:
mongodb:
host: 127.0.0.1
port: 27017
database: test
# 默认没有,有的可以加上
#username: admin
# 默认没有,有的可以加上
#password: 123456
插入
private void insert() {
mongoTemplate.insert(new UserInfo());
mongoTemplate.insert(new UserInfo(), "userInfo");
mongoTemplate.save(new UserInfo());
}
删除
private void remove() {
mongoTemplate.remove(new UserInfo());
DeleteResult deleteResult = mongoTemplate.remove(new UserInfo(), "userInfo");
// 是否执行成功
deleteResult.wasAcknowledged();
// 删除数量
deleteResult.getDeletedCount();
}
更新
private void update() {
// 原子操作
Update update = new Update();
update.inc("number", 1);
// 批量更新
mongoTemplate.updateMulti(new Query(), update, UserInfo.class);
// 更新第一条
mongoTemplate.updateFirst(new Query(), update, UserInfo.class);
// 更新数据, 如果不存在就插入
UpdateResult updateResult = mongoTemplate.upsert(new Query(), update, UserInfo.class);
// 是否执行成功
updateResult.wasAcknowledged();
// 匹配到的数量
updateResult.getMatchedCount();
// 更新数量
updateResult.getModifiedCount();
// 插入新数据的id
BsonValue upsertedId = updateResult.getUpsertedId();
}
查询
// 精确查询 { "username" : "admin" } 初始化 criteria 实例的两种方法
Criteria criteria = Criteria.where("username").is("admin");
Criteria cri = new Criteria("username").is("admin");
// 不等于查询 { "username" : { $ne : "admin" } }
Criteria ne = Criteria.where("username").ne("admin");
// 模糊查询 { "username" : /admin/ }
Criteria regex = Criteria.where("username").regex("^.*" + "admin" + ".*$");
// and 查询 { "username" : "admin", "phoneNumber" : "10086" }
Criteria and = criteria.and("phoneNumber").is("10086");
and = new Criteria().andOperator(Criteria.where("username").is("admin"),
Criteria.where("phoneNumber").is("10086"));
// or 查询 $or:[ { "username" : "admin" }, { "username" : "anonymous" } ]
Criteria or = criteria.orOperator(Criteria.where("username").is("admin"),
Criteria.where("username").is("anonymous"));
// in 查询 { "username" : { $in: ["admin", "anonymous"] } }
Criteria in = Criteria.where("username").in(Lists.newArrayList("admin", "anonymous"));
// nin 查询 { "username" : { $nin: ["admin", "anonymous"] } }
Criteria nin = Criteria.where("username").nin(Lists.newArrayList("admin", "anonymous"));
// lt/lte 比较查询
// 小于等于 { "crtDateTime": { $lte: ISODate("2001-01-01T00:00:00.000+08:00") } }
Criteria lte = Criteria.where("crtDateTime").lte(LocalDateTime.now());
// { "age": { $lte: 18 } }
lte = Criteria.where("age").lte(18);
// 小于 { "crtDateTime": {$lt: ISODate("2001-01-01T00:00:00.000+08:00") } }
Criteria lt = Criteria.where("crtDateTime").lt(LocalDateTime.now());
// { "age": { $lt: 18 } }
lt = Criteria.where("age").lt(18);
// gt/gte 比较查询
// 大于等于 { "crtDateTime": {$gte: ISODate("2001-01-01T00:00:00.000+08:00") } }
Criteria gte = Criteria.where("crtDateTime").gte(LocalDateTime.now());
// { "age": { $gte: 18 } }
gte = Criteria.where("age").gte(18);
// 大于 { "crtDateTime": {$gt: ISODate("2001-01-01T00:00:00.000+08:00") } }
Criteria gt = Criteria.where("crtDateTime").gt(LocalDateTime.now());
// { "age": { $gt: 18 } }
gt = Criteria.where("age").gt(18);
// 查询内嵌文档 { "usernameList" : { $elemMatch: { "username" : "admin" } } }
Criteria elemMatch = Criteria.where("usernameList").elemMatch(Criteria.where("username").is("admin"));
// api 中无具体接口的, 使用 document 拼接语句查询 { $expr : { $ne : [ "$A", "$B" ] } }
Criteria andDocumentStructureMatches = criteria.andDocumentStructureMatches(() ->
new Document().append("$expr", new Document("$ne", List.of("$A", "$B"))));
private void query() {
// 组装查询条件(参数 Criteria 的详细用法见 criteriaUsageSample())
Query query = new Query(Criteria.where("username").is("admin"));
// 查询唯一一条满足条件的数据(如果满足条件的数据多于1条,会报错)
UserInfo one = mongoTemplate.findOne(query, UserInfo.class);
// 查询满足条件的数据列表
List<UserInfo> list = mongoTemplate.find(query, UserInfo.class);
// 查询所有记录
List<UserInfo> all = mongoTemplate.findAll(UserInfo.class);
// 根据 filed 去重查询
List<UserInfo> distinctList = mongoTemplate.findDistinct(query, "username", UserInfo.class, UserInfo.class);
// 查询总数
long count = mongoTemplate.count(query, UserInfo.class);
}
参考:https://juejin.cn/post/7162094909045309470