Java研学-MongoDB(二)

一 数据库相关

1 show 命令 -- 展示数据库

javascript 复制代码
show dbs

2 use 命令 -- 创建数据库,初创时,数据库存在于内存,并未被持久化到磁盘无法通过show命令查询到,当数据库内有集合数据时,才会持久化到磁盘。

javascript 复制代码
// 创建数据库名为dahuang
use dahuang
switched to db dahuang

3 db 命令 -- 展示当前数据库

javascript 复制代码
dahuang> db
dahuang

4 db.dropDatabase() 命令 -- 删除数据库

javascript 复制代码
dahuang> db.dropDatabase()
{ ok: 1, dropped: 'dahuang' }

5 MongoDB 数据库命名须知

java 复制代码
非空字符串:数据库名不能是空字符串("")
禁用字符:
不能包含空格( )
不能包含美元符号($)
不能包含正斜杠(/)
不能包含反斜杠(\)
不能包含空字符(\0)
大小写建议:虽然 MongoDB 本身是大小写敏感的,但官方建议全部使用小写字母
长度限制:最多 64 字节(注意 UTF-8 字符可能占用多个字节)
java 复制代码
保留数据库(具有特殊作用):

admin 数据库:权限层面的"root"数据库;在此数据库中创建的用户会自动继承所有数据库的权限
某些管理命令只能从 admin 数据库运行,例如:列出所有数据库(db.adminCommand({listDatabases: 1}))
关闭服务器(db.shutdownServer())

local 数据库:其中的数据永远不会被复制到副本集的其他成员
适合存储仅限本地使用的集合;在副本集环境中特别有用

config 数据库:仅在分片集群环境中使用;存储分片集群的元数据和配置信息;普通用户通常不需要直接与之交互

二 集合相关

1 集合的显式创建

javascript 复制代码
// 引号内为集合的名称 xiaohuang
dahuang> db.createCollection("xiaohuang")
{ ok: 1 }

2 查询当前数据库的所有集合

javascript 复制代码
dahuang> show collections
xiaohuang

3 删除集合

javascript 复制代码
dahuang> db.xiaohuang.drop()
true

4 集合的隐式创建,当集合不存在,插入文档时可创建集合

javascript 复制代码
dahuang> db.xiaohuang.insertOne({ "name": "奔波儿灞", "job": "BA" })
{
  acknowledged: true,
  insertedId: ObjectId('684a8782d7de2ddda750eb68')
}

三 文档相关

1 单个文档插入

javascript 复制代码
// 向 xiaohuang 集合(表)中插入文档(一行数据)
// true 表示成功 insertedId 是为该数据生成的唯一标识码 _id 字段
dahuang> db.xiaohuang.insertOne({ "name": "奔波儿灞", "job": "BA" })
{
  acknowledged: true,
  insertedId: ObjectId('684a8782d7de2ddda750eb68')
}

2 多个文档插入

javascript 复制代码
dahuang> db.xiaohuang.insertMany([{ "name": "奔波儿灞", "job": "BA" },{ "name": "灞波儿奔", "job": "BA" }])
// true 表示成功
{
  acknowledged: true,
  insertedIds: {
    '0': ObjectId('684a88fcd7de2ddda750eb69'),
    '1': ObjectId('684a88fcd7de2ddda750eb6a')
  }
}

3 文档查询

javascript 复制代码
// 查所有
dahuang> db.xiaohuang.find()
[
  {
    _id: ObjectId('684a8782d7de2ddda750eb68'),
    name: '奔波儿灞',    
    job: 'BA'
  },
  {
    _id: ObjectId('684a88fcd7de2ddda750eb69'),
    name: '奔波儿灞',    
    job: 'BA'
  },
  {
    _id: ObjectId('684a88fcd7de2ddda750eb6a'),
    name: '灞波儿奔',    
    job: 'BA'
  }
]
javascript 复制代码
// 条件查询
dahuang> db.xiaohuang.find({name:"灞波儿奔"})
[
  {
    _id: ObjectId('684a88fcd7de2ddda750eb6a'),
    name: '灞波儿奔',
    job: 'BA'
  }
]
javascript 复制代码
// 多条查询结果,取第一条数据(类似limit)
dahuang> db.xiaohuang.findOne({name:"奔波儿灞"})
{ _id: ObjectId('684a8782d7de2ddda750eb68'), name: '奔波儿灞', job: 'BA' }
javascript 复制代码
// 部分字段查询(投影查询)1表示包含该字段,0表示不包含该字段,_id 字段默认被包含在结果中
dahuang> db.xiaohuang.find({name:"灞波儿奔"},{name:1,_id:0,job:1})
[ { name: '灞波儿奔', job: 'BA' } ]

4 try-catch事务使用

insertMany尝试将所有文档插入到集合中,但如果其中任何一个文档插入失败(例如,违反唯一约束、数据类型错误等),不会回滚已经成功插入的文档。因此需要使用事务。

即使某些文档插入失败,其他文档仍可能被成功插入。MongoDB 会返回一个错误对象,其中包含成功插入的文档数量和失败的原因。

javascript 复制代码
// 启动会话:db.getMongo().startSession() 创建一个新的会话。
const session = db.getMongo().startSession();
// 开启事务:session.startTransaction() 开始一个新的事务。
session.startTransaction();
// 执行操作:在事务中执行 insertMany 操作,并通过 { session } 选项将会话与操作关联
try {
    db.xiaohuang.insertMany([
        { "_id": "1", "content": "文档1" },
        { "_id": "2", "content": "文档2" }
    ], { session });
    // 提交事务:如果所有操作成功,调用 session.commitTransaction() 提交事务。
    session.commitTransaction();
} catch (e) {
    // 回滚事务:如果发生错误,调用 session.abortTransaction() 回滚事务。
    session.abortTransaction();
    print("事务失败: " + e);
} finally {
    // 结束会话:无论成功或失败,最后调用 session.endSession() 结束会话。
    session.endSession();
}

5 文档更新

① 语法:query为查询条件如{name:?}, update为更新条件配合原子操作符 ,options提供额外的更新选项,用于控制更新行为。

javascript 复制代码
// 单个文档更新(根据查询条件匹配到的第一个)
db.collection.updateOne(query,update,options)

// 多个文档更新(根据查询条件匹配到的所有)
db.collection.updateMany(query, update, options)

② 常见原子操作符:原子操作符是 MongoDB 更新操作的核心,用于精确控制文档字段的修改,确保操作的原子性和安全性。

javascript 复制代码
// $set 作用:设置或更新字段的值。
// 将 name 为 "Alice" 的文档的 age 设置为 30,status 设置为 "active"。
db.xiaohuang.updateOne(
  { name: "Alice" },
  { $set: { age: 30, status: "active" } }
);
javascript 复制代码
// $unset 作用:删除字段(即使字段不存在也不会报错)。
// 删除 name 为 "Alice" 的文档中的 deprecatedField 字段。
db.xiaohuang.updateOne(
  { name: "Alice" },
  { $unset: { deprecatedField: "" } }
);
javascript 复制代码
// $inc 作用:增加或减少数值字段的值(仅适用于数字类型)。
// 将 loginCount 增加 1,score 减少 5。
db.xiaohuang.updateOne(
  { name: "Alice" },
  { $inc: { loginCount: 1, score: -5 } }
);
javascript 复制代码
// $push 作用:向数组字段添加一个元素(若字段不存在则创建数组)。
// 向 tags 数组添加 "mongodb",向 hobbies 数组添加 "reading"。
db.xiaohuang.updateOne(
  { name: "Alice" },
  { $push: { tags: "mongodb", hobbies: "reading" } }
);
javascript 复制代码
// $addToSet 作用:向数组添加元素(仅当元素不存在时才添加,避免重复)。
// 如果 skills 数组中不存在 "javascript",则添加;否则忽略。
db.xiaohuang.updateOne(
  { name: "Alice" },
  { $addToSet: { skills: "javascript" } }
);
javascript 复制代码
// $pop 作用:从数组的开头或末尾移除一个元素。
// { $pop: { field: 1 } }:从末尾移除。{ $pop: { field: -1 } }:从开头移除。
db.xiaohuang.updateOne(
  { name: "Alice" },
  { $pop: { hobbies: 1 } } // 移除最后一个爱好
);
javascript 复制代码
// $pull 作用:从数组中移除所有匹配的元素。
// 从 tags 数组中移除所有值为 "deprecated" 的元素。
db.xiaohuang.updateOne(
  { name: "Alice" },
  { $pull: { tags: "deprecated" } }
);
javascript 复制代码
// $rename 作用:重命名字段。
// 将 oldName 字段重命名为 newName。
db.xiaohuang.updateOne(
  { name: "Alice" },
  { $rename: { "oldName": "newName" } }
);
javascript 复制代码
// $mul 作用:将字段的值乘以一个数字(仅适用于数字类型)。
db.xiaohuang.updateOne(
  { name: "Alice" },
  { $mul: { salary: 1.1 } } // 薪资增加 10%
);
javascript 复制代码
// $min/$max 作用:$min:仅当新值小于当前值时更新。$max:仅当新值大于当前值时更新。
// 将 oldName 字段重命名为 newName。
db.xiaohuang.updateOne(
  { name: "Alice" },
  { $min: { highScore: 100 } } // 仅当当前 highScore > 100 时更新
);
javascript 复制代码
// $currentDate 作用:将字段的值设置为当前日期(可设置为 Date 或 Timestamp)。
db.xiaohuang.updateOne(
  { name: "Alice" },
  { $currentDate: { lastLogin: true } } // 设置为当前时间
);

③ options 常用选项

javascript 复制代码
// upsert 类型:布尔值(true/false)默认:false
// 作用:如果为 true,当没有匹配的文档时,会插入一个新文档(结合 query 和 update 的内容)。
{ upsert: true }
javascript 复制代码
// writeConcern 类型:文档 
// 作用:指定写操作的写入确认级别(如 { w: 1, j: true }),控制数据持久化和副本集同步行为。
{ writeConcern: { w: "majority", j: true } }
javascript 复制代码
// bypassDocumentValidation 类型:布尔值(true/false)默认:false
// 作用:是否绕过集合的验证规则(需有权限)。
{ bypassDocumentValidation: true }
javascript 复制代码
// collation: 类型:文档
// 作用:指定排序规则(如语言特定的字符串比较规则)。
{ collation: { locale: "en", strength: 2 } }

④ 例子

javascript 复制代码
// 修改工作BA为CEO,默认只修改查询到的第一条文档数据
dahuang> db.xiaohuang.updateOne({ name: "奔波儿灞" },{ $set: { job: "CEO" }});
// 返回成功
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

// 文档数据
dahuang> db.xiaohuang.find()
[
  {
    _id: ObjectId('6854cae6f50f58c8c26c4bd0'),
    name: '奔波儿灞',
    job: 'CEO'
  },
  {
    _id: ObjectId('6854cae6f50f58c8c26c4bd1'),
    name: '灞波儿奔',
    job: 'BA'
  },
  {
    _id: ObjectId('6854db7ff50f58c8c26c4bd2'),
    name: '奔波儿灞',
    job: 'BA'
  },
  {
    _id: ObjectId('6854db7ff50f58c8c26c4bd3'),
    name: '灞波儿奔',
    job: 'BA'
  }
]
javascript 复制代码
// 当查询条件存在多个文档时,需添加选项 {multi:true},进行批量修改
dahuang> db.xiaohuang.update({name:"奔波儿灞"},{$set:{job:"CEO"}},{multi:true})
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 2,
  modifiedCount: 1,
  upsertedCount: 0
}

// 或者使用updateMany
dahuang> db.xiaohuang.updateMany({name:"灞波儿奔"},{$set:{job:"CEO"}})
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 2,
  modifiedCount: 2,
  upsertedCount: 0
}

// 文档数据
dahuang> db.xiaohuang.find()
[
  {
    _id: ObjectId('6854cae6f50f58c8c26c4bd0'),
    name: '奔波儿灞',
    job: 'CEO'
  },
  {
    _id: ObjectId('6854cae6f50f58c8c26c4bd1'),
    name: '灞波儿奔',
    job: 'BA'
  },
  {
    _id: ObjectId('6854db7ff50f58c8c26c4bd2'),
    name: '奔波儿灞',
    job: 'CEO'
  },
  {
    _id: ObjectId('6854db7ff50f58c8c26c4bd3'),
    name: '灞波儿奔',
    job: 'BA'
  }
]

6 文档删除

① 语法:

javascript 复制代码
// 删除单个文档
db.xiaohuang.deleteOne({条件})
 
// 删除多个匹配文档
db.xiaohuang.deleteMany({条件})

// 清空集合(包括索引)
db.xiaohuang.drop()

② 例子:

javascript 复制代码
// 删除前,先确认要删除的文档,再删除
db.xiaohuang.find({_id: "1"})
db.xiaohuang.remove({_id: "1"})

// 删除所有文档,但保留集合本身及其索引结构
db.xiaohuang.deleteMany({})
相关推荐
一切顺势而行3 分钟前
kafka总结
java
yanjiaweiya31 分钟前
云原生-集群管理
java·开发语言·云原生
gadiaola40 分钟前
【JavaSE面试篇】Java集合部分高频八股汇总
java·面试
艾迪的技术之路1 小时前
redisson使用lock导致死锁问题
java·后端·面试
今天背单词了吗9801 小时前
算法学习笔记:8.Bellman-Ford 算法——从原理到实战,涵盖 LeetCode 与考研 408 例题
java·开发语言·后端·算法·最短路径问题
天天摸鱼的java工程师1 小时前
使用 Spring Boot 整合高德地图实现路线规划功能
java·后端
东阳马生架构2 小时前
订单初版—2.生单链路中的技术问题说明文档
java
咖啡啡不加糖2 小时前
暴力破解漏洞与命令执行漏洞
java·后端·web安全
风象南2 小时前
SpringBoot敏感配置项加密与解密实战
java·spring boot·后端