当前位置: 首页 > news >正文

【MongoDB篇】MongoDB的文档操作!

在这里插入图片描述

目录

    • 引言
    • 第一节:C - Create - 创建文档 (Insert) 👶➕
    • 第二节:R - Read - 读取文档 (Query) 📚👀
    • 第三节:U - Update - 更新文档 (Update) 🔄✍️
    • 第四节:D - Delete - 删除文档 (Delete) 🗑️❌
    • 第五节:文档结构与 BSON 数据类型速览 🧱💾
    • 第六节:文档操作的考量与最佳实践 📏🔒 atom
    • 第七节:总结文档操作!🎉✍️

🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!

其他优质专栏: 【🎇SpringBoot】【🎉多线程】【🎨Redis】【✨设计模式专栏(已完结)】…等

如果喜欢作者的讲解方式,可以点赞收藏加关注,你的支持就是我的动力
✨更多文章请看个人主页: 码熔burning

看之前可以先了解一下MongoDB是什么:【MongoDB篇】万字带你初识MongoDB!

引言

好的!咱们一步一个脚印,从“仓库”(MongoDB)走到“房间”(数据库),再打开了“文件柜”(集合)。现在,终于来到了最最核心的地方——柜子里那些装满数据的 “文件”或者说“包裹”——文档 (Document)!📄

了解数据库操作请看:【MongoDB篇】MongoDB的数据库操作!
了解集合操作请看:【MongoDB篇】MongoDB的集合操作!

文档,是 MongoDB 中存储数据的基本单位!你所有实际的数据,不管是用户的名字、年龄、地址,还是商品的价格、库存、描述,亦或是文章的内容、作者、发布日期,统统都是以文档的形式存放在集合里的!

理解文档的操作,就是掌握了与 MongoDB“对话”的绝大部分技能!🚀 准备好了吗?请系好你的数据安全带,咱们要深入文档的奇妙世界了!✨


在 MongoDB 里,一个文档就是一个由键值对 (key-value pairs) 组成的结构。它的长相非常类似于我们熟悉的 JSON 对象!🤩 但在 MongoDB 的内部,文档存储的是 BSON (Binary JSON) 格式的数据。

BSON 相比 JSON 有啥优点?

  1. 支持更多数据类型:比如日期 (Date)、二进制数据 (Binary data)、ObjectId 等等,这些都是 JSON 原生不支持的。
  2. 更高效的存储和扫描:作为二进制格式,BSON 在存储空间和读写效率上通常优于纯文本的 JSON。

你可以把文档想象成一个非常灵活的包裹📦,你可以把任何你想放进去的数据(各种类型、各种结构)都塞到这个包裹里。

每个文档都有一个特殊的字段:_id。🔑

  • _id 字段是文档在集合中的唯一标识符,就像你的身份证号一样,不能重复!
  • 如果你在插入文档时没有指定 _id 字段,MongoDB 会自动为你生成一个全球唯一的 ObjectId 作为 _id。这个 ObjectId 包含了时间戳、机器 ID、进程 ID 和计数器,保证了其在分布式环境下的唯一性。
  • _id 字段默认会被自动索引,这使得通过 _id 查找文档非常快速!⚡

理解了文档的基本概念,接下来,我们就来学习如何对这些文档进行最核心的操作:CRUD (创建、读取、更新、删除)

第一节:C - Create - 创建文档 (Insert) 👶➕

往集合里“丢”包裹,就是创建文档!MongoDB 提供了两种主要的方法:

  1. insertOne(document, options):向集合中插入一个文档。

    use mydatabase; // 确保在正确的数据库
    // 插入一个简单的文档
    db.users.insertOne({name: "李四",age: 25,city: "上海"
    });// 插入一个带嵌套文档和数组的文档
    db.products.insertOne({name: "MongoDB T-Shirt",price: 25.99,tags: ["t-shirt", "clothing", "mongodb"],details: {color: "blue",size: ["S", "M", "L"]},in_stock: true,created_at: new Date()
    });// 插入一个指定 _id 的文档 (确保 _id 在集合中唯一)
    db.users.insertOne({_id: 1001, // 你也可以用数字、字符串等作为 _id,但 ObjectId 是推荐的默认值name: "王五",age: 35
    });
    
    • document: 你要插入的文档对象。
    • options: 可选参数,比如 writeConcern(写入安全级别)。

    insertOne() 会返回一个结果对象,其中包含 insertedId,就是插入文档的 _id

  2. insertMany([document1, document2, ...], options):向集合中插入多个文档(以文档数组的形式)。

    db.users.insertMany([{ name: "赵六", age: 22, city: "广州" },{ name: "孙七", age: 29, city: "北京", interests: ["coding", "travel"] },{ name: "周八", age: 31, city: "上海", company: "MongoDB Inc." }
    ]);
    
    • [document1, document2, ...]: 包含多个文档的数组。
    • options: 可选参数,比如 writeConcern,或者 ordered: boolean(是否按顺序插入,默认为 true。如果设置为 false,插入过程中即使遇到错误,也会继续插入其他文档)。

    insertMany() 会返回一个结果对象,包含 insertedIds,一个包含了所有插入文档 _id 的数组。

小贴士: 在进行大量数据导入时,insertMany 通常比循环调用 insertOne 效率更高,因为它减少了网络往返次数。🚀

第二节:R - Read - 读取文档 (Query) 📚👀

从集合里找出你想要的包裹,就是读取文档,也就是我们常说的查询 (Query)!这部分是与 MongoDB 交互中最常用、也最灵活的操作!

核心方法是 find(query, projection)findOne(query, projection)

  • find(query, projection):查找符合条件的所有文档,返回一个游标 (Cursor)。游标就像一个指向查询结果集的指针,你可以遍历游标来获取文档。
  • findOne(query, projection):查找符合条件的第一个文档。直接返回文档对象(如果找到的话),而不是游标。适合你知道查询结果只有一条或者你只关心第一条的场景。

query 参数 (查询文档)

find()findOne() 方法的第一个参数是一个查询文档 { ... },用来指定你想要查找的文档需要满足哪些条件。这是进行查询的关键!

查询选择器 (Query Selectors)

查询文档中,你可以使用各种查询选择器来构建复杂的查询条件。这些选择器通常以 $ 开头。哥在之前的“操作大全”里已经列举了一些,这里再针对文档查询,把最常用的详细展开一下,并给出更清晰的例子!

假设我们操作 users 集合,文档结构类似 { name: "...", age: ..., city: "...", interests: [...] }

  1. 相等匹配:

    db.users.find({ name: "李四" }); // 查找 name 等于 "李四" 的文档
    db.users.find({ age: 25 });      // 查找 age 等于 25 的文档
    db.users.find({ _id: ObjectId("...") }); // 根据 _id 查找文档 (非常高效!)
    
  2. 比较查询 ($gt, $lt, $gte, $lte, $ne, $in, $nin):

    db.users.find({ age: { $gt: 30 } });     // 查找 age 大于 30 的文档
    db.users.find({ age: { $lte: 25 } });    // 查找 age 小于等于 25 的文档
    db.users.find({ city: { $ne: "上海" } }); // 查找 city 不等于 "上海" 的文档
    db.users.find({ city: { $in: ["北京", "上海"] } }); // 查找 city 在 "北京" 或 "上海" 中的文档
    db.users.find({ interests: { $nin: ["coding"] } }); // 查找 interests 数组中不包含 "coding" 的文档
    
  3. 逻辑查询 ($and, $or, $not, $nor):

    // 查找 age > 28 且 city 是“广州”的文档
    db.users.find({ $and: [{ age: { $gt: 28 } }, { city: "广州" }] });
    // 简写形式 (多个键值对默认就是 AND 关系): db.users.find({ age: { $gt: 28 }, city: "广州" });// 查找 city 是“北京”或 age < 25 的文档
    db.users.find({ $or: [{ city: "北京" }, { age: { $lt: 25 } }] });// 查找 age 不大于 30 的文档 (等价于 age <= 30)
    db.users.find({ age: { $not: { $gt: 30 } } });
    
  4. 元素查询 ($exists, $type):

    db.users.find({ interests: { $exists: true } }); // 查找存在 interests 字段的文档
    db.users.find({ company: { $exists: false } }); // 查找不存在 company 字段的文档
    db.users.find({ age: { $type: "number" } });   // 查找 age 字段类型是 number 的文档 (数字类型细分为 double, int, long, decimal)
    db.users.find({ name: { $type: "string" } });   // 查找 name 字段类型是 string 的文档
    

    你可以用 db.mycollection.find().forEach(doc => { for(const key in doc) { print(key + ': ' + typeof doc[key] + ', BSON type: ' + BSON.type(doc[key])); } }); 来查看文档中字段的 BSON 类型。

  5. 评估查询 ($regex, $expr):

    db.users.find({ name: { $regex: /^李/ } }); // 查找 name 以“李”开头的文档
    db.users.find({ name: { $regex: /八$/, $options: 'i' } }); // 查找 name 以“八”结尾的文档,不区分大小写 ('i')// 使用 $expr 查找 age 大于 interests 数组长度的文档
    db.users.find({ $expr: { $gt: ["$age", { $size: "$interests" }] } });
    
  6. 数组查询 ($all, $elemMatch, $size):

    db.users.find({ interests: { $all: ["coding", "travel"] } }); // 查找 interests 数组同时包含 "coding" 和 "travel" 的文档 (顺序不重要)db.users.find({ interests: "coding" }); // 查找 interests 数组包含 "coding" 的文档 (这是 $elemMatch 的简写形式)// 查找 interests 数组中至少有一个元素匹配特定条件的文档
    db.users.find({ interests: { $elemMatch: { $regex: /^code/ } } }); // 查找 interests 数组中某个元素以 "code" 开头db.users.find({ interests: { $size: 2 } }); // 查找 interests 数组长度为 2 的文档
    

projection 参数 (投影文档)

find()findOne() 的第二个参数是一个投影文档 { ... },用来指定你希望在返回结果中包含或排除哪些字段。默认情况下,会返回文档的所有字段(包括 _id)。

  • { field: 1, ... }: 指定需要包含的字段。_id 字段默认包含,如果你不想要 _id,需要显式设置为 _id: 0
  • { field: 0, ... }: 指定需要排除的字段。不能在同一个投影文档中同时使用包含和排除(_id 除外)。
db.users.find({}, { name: 1, city: 1 }); // 查找所有文档,只返回 name, city 字段和 _id
db.users.find({}, { interests: 0 });      // 查找所有文档,排除 interests 字段
db.users.find({}, { name: 1, _id: 0 });   // 查找所有文档,只返回 name 字段,排除 _id

链式调用查询辅助方法:

find() 方法返回的是一个游标,你可以在游标上链式调用各种方法来进一步 refining 你的查询结果:

  • .sort({ field: 1/-1 }):对结果进行排序。1 升序,-1 降序。

    db.users.find().sort({ age: -1 }); // 按年龄降序排序
    
  • .limit(number):限制返回的文档数量。

    db.users.find().limit(5); // 只返回前 5 个文档
    
  • .skip(number):跳过指定数量的文档。常用于分页。

    db.users.find().skip(10).limit(10); // 跳过前 10 个,返回接下来的 10 个 (第二页)
    
  • .count():计算符合查询条件的文档数量(已废弃,请用 countDocumentsestimatedDocumentCount)。

  • .countDocuments(query):精确计数。

  • .estimatedDocumentCount():快速估算总数。

    db.users.countDocuments({ city: "北京" }); // 精确计算北京用户的数量
    db.users.estimatedDocumentCount();      // 快速估算 users 集合总文档数
    

掌握查询操作,就像拥有了一双“火眼金睛”👀,你可以从海量数据中准确地找到你想要的那一份!多练习各种选择器和组合,你就是查询界的“卷王”!💪

第三节:U - Update - 更新文档 (Update) 🔄✍️

找到文档后,你可能需要修改它里面的内容。这就是更新操作!

核心方法是 updateOne(query, update, options), updateMany(query, update, options), 和 replaceOne(query, replacement, options)

  • updateOne(query, update, options):更新符合 query 条件的第一个文档。
  • updateMany(query, update, options):更新符合 query 条件的所有文档。
  • replaceOne(query, replacement, options):用 replacement 文档完全替换符合 query 条件的第一个文档。

update 参数 (更新操作文档)

更新操作(除了 replaceOne)的核心在于使用更新操作符 (Update Operators)!你不能直接传一个 { field: new_value } 这样的文档去更新,那样会替换整个文档(除非你用的是 replaceOne)!你需要用 $set, $inc 等操作符告诉 MongoDB 如何修改文档。

更新操作文档的结构通常是 { $operator: { field: value, ... }, $anotherOperator: { ... } }

更新操作符 (Update Operators)

哥在之前的“操作大全”里也介绍了一些,这里结合文档操作,再详细讲讲最常用的!

假设我们操作 users 集合

  1. 字段更新操作符 ($set, $unset, $inc, $mul, $rename):

    • $set: 设置或修改字段的值。如果字段不存在,则添加该字段。最常用!

      // 将 李四 的 age 改为 26
      db.users.updateOne({ name: "李四" }, { $set: { age: 26 } });
      // 给 李四 添加一个 email 字段
      db.users.updateOne({ name: "李四" }, { $set: { email: "lisi@example.com" } });
      // 同时修改多个字段
      db.users.updateOne({ name: "李四" }, { $set: { age: 27, city: "深圳" } });
      
    • $unset: 删除字段。值不重要,只要存在就行。

      // 删除 李四 的 email 字段
      db.users.updateOne({ name: "李四" }, { $unset: { email: "" } });
      
    • $inc: 字段值增加指定的数值。

      // 给所有用户的 age 增加 1
      db.users.updateMany({}, { $inc: { age: 1 } });
      
    • $mul: 字段值乘以指定的数值。

      // 将 李四 的 age 乘以 2
      db.users.updateOne({ name: "李四" }, { $mul: { age: 2 } });
      
    • $rename: 重命名字段。

      // 将所有文档的 interests 字段重命名为 hobbies
      db.users.updateMany({}, { $rename: { interests: "hobbies" } });
      
  2. 数组更新操作符 ($push, $addToSet, $pop, $pull, $pullAll, $each, $slice, $sort, $position):

    • $push: 向数组末尾添加一个元素。

      // 给 赵六 的 hobbies 数组添加一个兴趣 "看电影"
      db.users.updateOne({ name: "赵六" }, { $push: { hobbies: "看电影" } });
      
    • $addToSet: 向数组中添加一个元素,只有当该元素不在数组中时才添加(保证唯一性)。

      // 给 赵六 的 hobbies 数组添加 "听音乐",如果已经有了就不添加
      db.users.updateOne({ name: "赵六" }, { $addToSet: { hobbies: "听音乐" } });
      
    • $pop: 从数组的头部 (-1) 或尾部 (1) 删除一个元素。

      // 删除 赵六 的 hobbies 数组的最后一个元素
      db.users.updateOne({ name: "赵六" }, { $pop: { hobbies: 1 } });
      // 删除 赵六 的 hobbies 数组的第一个元素
      db.users.updateOne({ name: "赵六" }, { $pop: { hobbies: -1 } });
      
    • $pull: 从数组中删除所有匹配指定条件的元素。

      // 删除 赵六 hobbies 数组中所有值为 "看电影" 的元素
      db.users.updateOne({ name: "赵六" }, { $pull: { hobbies: "看电影" } });
      
    • $pullAll: 从数组中删除所有匹配指定值列表的元素。

      // 删除 赵六 hobbies 数组中值为 "听音乐" 和 "爬山" 的元素
      db.users.updateOne({ name: "赵六" }, { $pullAll: { hobbies: ["听音乐", "爬山"] } });
      
    • $each, $slice, $sort, $position: 与 $push 结合使用,用于批量添加、限制数组大小、排序、指定插入位置。

      // 给 赵六 的 hobbies 数组添加多个兴趣 ["跑步", "游泳"]
      db.users.updateOne({ name: "赵六" }, { $push: { hobbies: { $each: ["跑步", "游泳"] } } });// 添加一个兴趣,并保留 hobbies 数组的最后 3 个元素
      db.users.updateOne({ name: "赵六" }, { $push: { hobbies: { $each: ["徒步"], $slice: -3 } } });// 添加一个兴趣,并对 hobbies 数组进行升序排序
      db.users.updateOne({ name: "赵六" }, { $push: { hobbies: { $each: ["滑雪"], $sort: 1 } } });// 在 hobbies 数组的第二个位置 (索引 1) 插入一个兴趣 "摄影"
      db.users.updateOne({ name: "赵六" }, { $push: { hobbies: { $each: ["摄影"], $position: 1 } } });
      

replaceOne(query, replacement, options)

这个操作不使用更新操作符,而是用 replacement 文档完全替换符合 query 条件的第一个文档。原文档中没有在 replacement 中出现的字段都会被移除!

// 找到名字是"李四"的文档,用一个新的文档完全替换它
db.users.replaceOne({ name: "李四" }, { name: "李四 New", status: "active", last_updated: new Date() });
// 原文档中李四的 age, city 字段会被移除,只剩下 name, status, last_updated 和 _id

options 参数 (更新选项)

updateOne, updateMany, replaceOne 都支持一些选项,最常用的是 upsert

  • upsert: boolean:如果设置为 true,当没有找到符合 query 条件的文档时,MongoDB 会根据 queryupdatereplacement 参数插入一个新的文档。

    // 尝试更新名字是"不存在的人"的文档,如果不存在,就插入一个新文档
    db.users.updateOne({ name: "不存在的人" },{ $set: { status: "inactive" } },{ upsert: true } // 因为不存在,所以会插入 { name: "不存在的人", status: "inactive", _id: ... }
    );
    

更新操作是 MongoDB 灵活性的重要体现。通过各种更新操作符,你可以对文档的结构和内容进行非常精细和高效的修改!熟练掌握它们,你的文档操作能力将大幅提升!🚀

第四节:D - Delete - 删除文档 (Delete) 🗑️❌

不需要的文档,直接“扔掉”!🗑️

核心方法是 deleteOne(query, options)deleteMany(query, options)

  • deleteOne(query, options):删除符合 query 条件的第一个文档。
  • deleteMany(query, options):删除符合 query 条件的所有文档。

query 参数 (查询文档)

跟查询操作一样,delete 操作的第一个参数也是一个查询文档 { ... },用来指定要删除哪些文档。

use mydatabase; // 确保在正确的数据库// 删除名字是"不存在的人"的文档
db.users.deleteOne({ name: "不存在的人" });// 删除所有年龄小于 25 的文档
db.users.deleteMany({ age: { $lt: 25 } });// 删除所有 city 是"上海"且 age 大于 30 的文档
db.users.deleteMany({ city: "上海", age: { $gt: 30 } });// **危险操作!** 删除 users 集合中的所有文档!务必谨慎!💣💥
db.users.deleteMany({});

警告: 删除操作是不可逆的!被删除的文档无法直接恢复!在执行 deleteMany({}) 这样的操作之前,一定要再三确认你的意图和目标集合!否则,你可能会失去所有宝贵的数据!😭

第五节:文档结构与 BSON 数据类型速览 🧱💾

一个文档就是由键值对组成的 BSON 对象。键(key)是字符串,值(value)可以是各种 BSON 支持的数据类型。

常见的 BSON 数据类型包括:

  • String:字符串
  • Integer (32-bit / 64-bit):整数,MongoDB 会根据数值大小自动选择存储类型
  • Double:双精度浮点数
  • Boolean:布尔值 (truefalse)
  • Array:数组,值可以是任何 BSON 数据类型,可以嵌套数组。
  • Object / Embedded Document:嵌套文档,文档中可以包含子文档,形成层级结构。
  • ObjectId:12 字节的唯一 ID,MongoDB 自动生成,通常用作 _id
  • Date:日期和时间,存储为 Unix 时间戳(自 epoch 以来的毫秒数)。
  • Binary Data:二进制数据。
  • Null:表示字段值为 null。
  • Undefined:表示字段未定义 (已废弃,不推荐使用)。
  • Regular Expression:正则表达式。
  • Timestamp:时间戳,主要用于内部操作,比如复制集。
  • Decimal128:高精度十进制数,适合处理货币等需要精确计算的场景。

理解这些数据类型,有助于你更好地设计文档结构和进行数据操作。

第六节:文档操作的考量与最佳实践 📏🔒 atom

进行文档操作时,有一些重要的考量和最佳实践:

  • 文档大小限制:MongoDB 对单个文档的大小有限制,目前是 16MB。如果你的文档超过这个大小,将无法插入或更新。设计文档结构时要考虑到这一点。对于大型二进制数据(如图片),通常建议存储在文件存储系统(如 S3、GridFS 等)中,文档中只存储文件引用。
  • _id 的重要性_id 是文档的唯一标识,并且自动带索引,通过 _id 进行查询非常高效。在设计文档时,思考如何利用 _id 或其他唯一字段来快速定位文档。
  • 内嵌文档 vs 引用:在设计一对一或一对多关系时,你可以选择使用内嵌文档(将相关文档直接嵌套在父文档中)或者使用引用(在父文档中存储相关文档的 _id)。
    • 内嵌:查询效率高(无需 JOIN),但可能导致文档过大、数据冗余(如果内嵌的数据经常被修改)。
    • 引用:避免文档过大和数据冗余,但查询时可能需要进行额外的查询(类似 JOIN)。
      选择哪种方式取决于你的访问模式:如果内嵌数据经常与父文档一起访问,且不经常更新,内嵌是好选择;如果内嵌数据很大或经常独立更新,引用可能更好。
  • 单文档原子性:在 MongoDB 中,对单个文档的更新操作是原子性的。这意味着你在修改一个文档时,要么所有修改都成功,要么都不成功,不会出现修改了一半的情况。但是,跨文档的操作默认不是原子性的!如果你需要保证多个文档操作的原子性,就需要使用多文档事务(如我们之前提到的)。
  • 权限:进行文档的增删改查操作,需要用户拥有对应集合所在数据库的 read, readWrite, update, remove 等角色权限。

第七节:总结文档操作!🎉✍️

恭喜你!🎉 你已经掌握了 MongoDB 最核心的知识点——文档的 CRUD 操作!从创建、读取(包括各种复杂的查询)、更新(包括强大的更新操作符)到删除,你已经具备了与 MongoDB 数据库中的数据进行交互的基本能力!

文档是 MongoDB 的灵魂,灵活的文档模型和强大的操作符让你可以非常自由地处理各种数据结构。

希望这篇关于文档的详细讲解对你有所帮助!实践是最好的老师,现在就去你的 MongoDB 环境里,尽情地对文档进行 CRUD 操作吧!去玩转你的数据!😎

相关文章:

【MongoDB篇】MongoDB的文档操作!

目录 引言第一节&#xff1a;C - Create - 创建文档 (Insert) &#x1f476;➕第二节&#xff1a;R - Read - 读取文档 (Query) &#x1f4da;&#x1f440;第三节&#xff1a;U - Update - 更新文档 (Update) &#x1f504;✍️第四节&#xff1a;D - Delete - 删除文档 (Dele…...

详解具身智能机器人开源数据集:RoboMIND

一、RoboMIND基础信息 RoboMIND 发布时间&#xff1a;2024年12月 创建方&#xff1a;国家地方共建具身智能机器人创新中心与北京大学计算机学院联合创建。 所使用的机器人&#xff1a;单臂机器人&#xff08;Franka Emika Panda 、UR5e &#xff09;、双臂机器人&#xff08;…...

施磊老师rpc(一)

文章目录 mprpc项目**项目概述**&#xff1a;深入学习到什么**前置学习建议**&#xff1a;核心内容其他技术与工具**项目特点与要求**&#xff1a;**环境准备**&#xff1a; 技术栈集群和分布式理论单机聊天服务器案例分析集群聊天服务器分析分布式系统介绍多个模块的局限引入分…...

视觉问答大模型速递:Skywork-R1V2-38B

Skywork-R1V2-38B速读 一、模型概述 Skywork-R1V2-38B是一种最先进的开源多模态推理模型&#xff0c;在多项基准测试中表现卓越。它在MMMU测试中以73.6%的得分位居所有开源模型之首&#xff0c;在OlympiadBench测试中以62.6%的得分大幅领先于其他开源模型。此外&#xff0c;R…...

Spring Boot 中集成 Kafka 并实现延迟消息队列

在 Spring Boot 中集成 Kafka 并实现延迟消息队列,需要结合 Kafka 的基础功能与自定义逻辑来处理延迟投递。以下是完整的实现步骤和示例代码,涵盖配置、生产者、消费者、延迟队列设计和消息重试机制。 一、环境准备与依赖配置 添加依赖 在 pom.xml 中添加 Spring Kafka 依赖:…...

【算法学习】哈希表篇:哈希表的使用场景和使用方法

算法学习&#xff1a; https://blog.csdn.net/2301_80220607/category_12922080.html?spm1001.2014.3001.5482 前言&#xff1a; 在之前学习数据结构时我们就学习了哈希表的使用方法&#xff0c;这里我们主要是针对哈希表的做题方法进行讲解&#xff0c;都是leetcode上的经典…...

(51单片机)LCD显示红外遥控相关数据(Delay延时函数)(LCD1602教程)(Int0和Timer0外部中断教程)(IR红外遥控模块教程)

前言&#xff1a; 本次Timer0模块改装了一下&#xff0c;注意&#xff01;&#xff01;&#xff01; 演示视频&#xff1a; 红外遥控 源代码&#xff1a; 如上图将9个文放在Keli5 中即可&#xff0c;然后烧录在单片机中就行了 烧录软件用的是STC-ISP&#xff0c;不知道怎么安…...

农产品园区展示系统——仙盟创梦IDE开发

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>农业大数据平台</title><style>* {margi…...

Copilot:您的AI伴侣-微软50周年系列更新

回顾微软五十年来持续创新带来的深远影响&#xff0c;比尔盖茨当年"让每张办公桌、每个家庭都拥有电脑"的宏伟愿景至今仍激励着我们。微软AI团队正秉承同样的精神&#xff0c;打造属于每个人的AI伙伴——Copilot。 这意味着什么&#xff1f;它是什么模样&#xff1f…...

【人工智能】深入探索Python中的自然语言理解:实现实体识别系统

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 自然语言理解(NLU)是人工智能(AI)领域中的重要研究方向之一,其目标是让计算机理解和处理人类语言。在NLU的众多应用中,实体识别(Nam…...

​​Steam安装下载及新手注册

&#x1f4e2;博客主页&#xff1a;肩匣与橘 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由肩匣与橘编写&#xff0c;首发于CSDN&#x1f649; &#x1f4e2;生活依旧是美好而又温柔的&#xff0c;你也…...

Gradio全解20——Streaming:流式传输的多媒体应用(1)——流式传输音频:魔力8号球

Gradio全解20——Streaming&#xff1a;Streaming&#xff1a;流式传输的多媒体应用&#xff08;1&#xff09;——流式传输音频&#xff1a;魔力8号球 前言本篇摘要20. Streaming&#xff1a;流式传输的多媒体应用20.1 流式传输音频&#xff1a;魔力8号球20.1.1 工作原理20.1.…...

Netflix系统架构解析

Netflix系统架构解析 Netflix架构旨在高效可靠地同时为数百万用户提供内容。以下是其特性和组件的详细分析。 是否曾好奇Netflix如何让您目不转睛地享受无中断的流畅播放体验&#xff1f;幕后功臣正是Netflix架构&#xff0c;它负责提供吸引全球观众的无缝流媒体体验。Netflix的…...

宝塔面板运行docker的jenkins

1.在宝塔面板装docker&#xff0c;以及jenkins 2.ip:端口访问jenkins 3.获取密钥&#xff08;点击日志&#xff09; 4.配置容器内的jdk和maven环境&#xff08;直接把jdk和maven文件夹放到jenkins容器映射的data文件下&#xff09; 点击容器-->管理-->数据存储卷--.把相…...

【计算机视觉】目标检测:深度解析Detectron2:Meta开源目标检测与图像分割框架实战指南

深度解析Detectron2&#xff1a;Meta开源目标检测与图像分割框架实战指南 技术架构与设计哲学核心设计理念关键技术组件 环境配置与安装硬件建议配置详细安装步骤 实战流程详解1. 自定义数据集准备2. 模型配置与训练3. 模型评估与推理 核心功能扩展1. 自定义模型架构2. 混合精度…...

Notepad编辑器实现换行符替换

在不同的Note编辑器中&#xff0c;批量把换行替换为空的方法有所不同&#xff0c;以下是常见编辑器的操作方法&#xff1a; Notepad 打开文件后&#xff0c;按CtrlH打开“查找和替换”对话框&#xff0c;在“查找”字段中输入\r\n&#xff0c;在“替换为”字段中输入一个空格…...

【数据通信完全指南】从物理层到协议栈的深度解析

目录 1. 通信技术演进与核心挑战1.1 从电报到5G的技术变迁1.2 现代通信系统的三大瓶颈 2. 通信系统架构深度解构2.1 OSI七层模型运作原理2.2 TCP/IP协议栈实战解析 3. 物理层关键技术实现3.1 信号调制技术演进路线3.2 信道复用方案对比 4. 数据传输可靠性保障4.1 CRC校验算法数…...

SpringBoot多工程项目微服务install时如何不安装到本地仓库

在 Spring Boot 微服务项目中&#xff0c;比如各业务微服务模块由于不存在相互依赖度的问题&#xff0c;因此执行maven install时无需安装到本地仓库&#xff0c;但仍然需要参与构建&#xff08;如 mvn compile 或 mvn package&#xff09;。公共模块&#xff08;如​​辅助工具…...

强化学习_Paper_2017_Curiosity-driven Exploration by Self-supervised Prediction

paper Link: ICM: Curiosity-driven Exploration by Self-supervised Prediction GITHUB Link: 官方: noreward-rl 1- 主要贡献 对好奇心进行定义与建模 好奇心定义&#xff1a;next state的prediction error作为该state novelty 如果智能体真的“懂”一个state&#xff0c;那…...

iview内存泄漏

iview在升级到view-design之前&#xff0c;是存在严重的内存泄漏问题的&#xff0c;而如果你在项目中大量使用了iview组件&#xff0c;就可能面临大量的升级工作要做&#xff0c;因为样式很多是不兼容的。 我们今天就看一下iview的源码&#xff0c;看看到底问题在哪里&#xff…...

【Hive入门】Hive高级特性:事务表与ACID特性详解

目录 1 Hive事务概述 2 ACID特性详解 3 Hive事务表的配置与启用 3.1 启用Hive事务支持 3.2 创建事务表 4 Hive事务操作流程 5 并发控制与隔离级别 5.1 Hive的锁机制 5.2 隔离级别 6 Hive事务的限制与优化 6.1 主要限制 6.2 性能优化建议 7 事务表操作示例 7.1 基本…...

Modbus转PROFIBUS网关:电动机保护新突破!

Modbus转PROFIBUS网关&#xff1a;电动机保护新突破&#xff01; 在现代工业自动化领域&#xff0c;Modbus RTU和PROFIBUS DP是两种常见且重要的通讯协议。它们各自具有独特的优势和应用场景&#xff0c;但在实际工程中&#xff0c;我们常常需要将这两种不同协议的设备进行互联…...

大数据应用开发和项目实战-Seaborn

设计目标 seaborn 建立在 matplotlib 之上&#xff0c;专注于统计数据可视化&#xff0c;简化绘图过程&#xff0c;提供高级接口和美观的默认主题 Seaborn的安装&#xff1a; 1.pip install seaborn -i 2.conda install seaborn &#xff08;清华源&#xff1a;https://pypi.t…...

弹窗探索鸿蒙之旅:揭秘弹窗的本质与奥秘

嘿&#xff0c;小伙伴们&#xff01;&#x1f44b; 今天我们要一起探索那些在日常应用中无处不在的小精灵——弹窗&#xff01;&#x1f4ac; &#x1f914; ‌弹窗到底是什么&#xff1f;‌ 简单来说&#xff0c;弹窗就是应用程序中突然冒出来的交互元素&#xff0c;它们像…...

“技术创新+全球视野”良性驱动,首航新能的2025新征程正式起航

撰稿 | 行星 来源 | 贝多财经 近日&#xff0c;备受瞩目的“2025年光伏第一股”深圳市首航新能源股份有限公司&#xff08;301658.SZ&#xff0c;下称“首航新能”&#xff09;对外发布了上市后的首份年报&#xff0c;交出了一份量质齐升的业绩答卷&#xff0c;构筑更加强大的…...

黑群晖Moments视频无缩略图,安装第三方ffmpeg解决

黑群晖Moments视频无缩略图&#xff0c;安装第三方ffmpeg解决 1. 设置套件来源 黑群晖Moments视频无缩略图&#xff0c;安装第三方ffmpeg解决 基于这个文章&#xff0c;补充一下&#xff1a; 1. 设置套件来源 设置套件来源时(http://packages.synocommunity.com)&#xff0c…...

工业控制「混合架构」PK大战 —— 神经网络 + MPC vs 模糊 PID+MPC 的场景选型与实战指南

1. 引言 在工业控制领域&#xff0c;传统的 PID 控制器因其结构简单、稳定性好而被广泛应用&#xff0c;但面对复杂非线性系统时往往力不从心。模型预测控制&#xff08;MPC&#xff09;作为一种基于模型的先进控制策略&#xff0c;能够有效处理多变量、多约束问题&#xff0c…...

树莓派智能摄像头实战指南:基于TensorFlow Lite的端到端AI部署

引言&#xff1a;嵌入式AI的革新力量 在物联网与人工智能深度融合的今天&#xff0c;树莓派这一信用卡大小的计算机正在成为边缘计算的核心载体。本文将手把手教你打造一款基于TensorFlow Lite的低功耗智能监控设备&#xff0c;通过MobileNetV2模型实现实时物体检测&#xff0…...

OpenCV 图形API(73)图像与通道拼接函数-----执行 查找表操作图像处理函数LUT()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 对矩阵执行查找表变换。 函数 LUT 使用来自查找表中的值填充输出矩阵。输入矩阵中的值作为查找表的索引。也就是说&#xff0c;函数对 src 中的…...

【MySQL】增删改查(CRUD)

目录 一. CRUD是什么 二. Create&#xff08;新增数据&#xff09; 2.1 单行数据全列插入 2.2 单行数据指定列插入 2.3 多行数据指定列插入 三. Retrieve &#xff08;检索/查询&#xff09; 3.1 全列查询 3.2 指定列查询 3.3 查询字段为表达式 3.4 为查询结果指定别名 3…...

iview 如何设置sider宽度

iview layout组件中&#xff0c;sider设置了默认宽度和最大宽度&#xff0c;在css样式文件中修改无效&#xff0c;原因是iview默认样式设置在了element.style中&#xff0c;只能通过行内样式修改 样式如下&#xff1a; image.png image.png 修改方式&#xff1a; 1.官方文档中写…...

Unity URP RenderTexture优化(二):深度图优化

目录 前言&#xff1a; 一、定位深度信息 1.1&#xff1a;k_DepthStencilFormat 1.2&#xff1a;k_DepthBufferBits 1.3&#xff1a;_CameraDepthTexture精度与大小 1.4&#xff1a;_CameraDepthAttachment数量 二、全代码 前言&#xff1a; 在上一篇文章&#xff1a;Un…...

iview表单提交验证时,出现空值参数被过滤掉不提交的问题解决

如图所示 有时候在表单提交的时候 个别参数是空值&#xff0c;但是看提交接口的反馈 发现空值的参数根本没传 这是因为表单验证给过滤掉了空值&#xff0c;有时候如果空值传不传都不无所谓&#xff0c;那可以不用管&#xff0c;但如果就算是空值也得传的吗&#xff0c;那就需要…...

GEO vs SEO:从搜索引擎到生成引擎的优化新思路

随着人工智能技术的快速发展&#xff0c;生成引擎优化&#xff08;GEO&#xff09;作为一种新兴的优化策略&#xff0c;逐渐成为企业和内容创作者关注的焦点。与传统的搜索引擎优化&#xff08;SEO&#xff09;相比&#xff0c;GEO不仅关注如何提升内容在搜索结果中的排名&…...

Python-pandas-操作csv文件(读取数据/写入数据)及csv语法详细分享

Python-pandas-操作csv文件(读取数据/写入数据) 提示&#xff1a;帮帮志会陆续更新非常多的IT技术知识&#xff0c;希望分享的内容对您有用。本章分享的是pandas的使用语法。前后每一小节的内容是存在的有&#xff1a;学习and理解的关联性。【帮帮志系列文章】&#xff1a;每个…...

如何在Windows上实现MacOS中的open命令

在MacOS的终端中&#xff0c;想要快速便捷的在Finder中打开当前目录&#xff0c;直接使用oepn即可。 open . 但是Windows中没有直接提供类似open这样的命令&#xff0c;既然没有直接提供&#xff0c;我们就间接手搓一个实现它。 步骤1&#xff1a;创建open.bat echo OFF expl…...

读论文笔记-LLaVA:Visual Instruction Tuning

读论文笔记-LLaVA&#xff1a;Visual Instruction Tuning 《Visual Instruction Tuning》 研究机构&#xff1a;Microsoft Research 发表于2023的NeurIPS Problems 填补指令微调方法&#xff08;包括数据、模型、基准等&#xff09;在多模态领域的空白。 Motivations 人工…...

Vue3源码学习3-结合vitetest来实现mini-vue

文章目录 前言✅ 当前已实现模块汇总&#xff08;mini-vue&#xff09;✅ 每个模块简要源码摘要1. reactive.ts2. effect.ts3. computed.ts4. ref.ts5. toRef.ts6. toRefs.ts ✅ 下一阶段推荐目标所有核心模块对应的 __tests__ 测试文件&#xff0c;**带完整注释**✅ reactive.…...

K8S - 从零构建 Docker 镜像与容器

一、基础概念 1.1 镜像&#xff08;Image&#xff09; “软件的标准化安装包” &#xff0c;包含代码、环境和配置的只读模板。 技术解析 镜像由多个层组成&#xff0c;每层对应一个Dockerfile指令&#xff1a; 应用代码 → 运行时环境 → 系统工具链 → 启动配置核心特性…...

贪心算法求解边界最大数

贪心算法求解边界最大数&#xff08;拼多多2504、排列问题&#xff09; 多多有两个仅由正整数构成的数列 s1 和 s2&#xff0c;多多可以对 s1 进行任意次操作&#xff0c;每次操作可以置换 s1 中任意两个数字的位置。多多想让数列 s1 构成的数字尽可能大&#xff0c;但是不能比…...

C++类和对象(中)

类的默认成员函数 默认成员函数就是用户没有显式实现&#xff0c;编译器会自动生成的成员函数。一个类&#xff0c;我们不写的情况下编译器会默认生成6个默认成员函数&#xff0c;C11以后还会增加两个默认成员函数&#xff0c;移动构造和移动赋值。默认成员函数 很重要&#x…...

(Go Gin)Gin学习笔记(五)会话控制与参数验证:Cookie使用、Sessions使用、结构体验证参数、自定义验证参数

1. Cookie介绍 HTTP是无状态协议&#xff0c;服务器不能记录浏览器的访问状态&#xff0c;也就是说服务器不能区分两次请求是否由同一个客户端发出Cookie就是解决HTTP协议无状态的方案之一&#xff0c;中文是小甜饼的意思Cookie实际上就是服务器保存在浏览器上的一段信息。浏览…...

Windows 10 环境二进制方式安装 MySQL 8.0.41

文章目录 初始化数据库配置文件注册成服务启停服务链接服务器登录之后重置密码卸载 初始化数据库 D:\MySQL\MySQL8.0.41\mysql-8.0.41-winx64\mysql-8.0.41-winx64\bin\mysqld -I --console --basedirD:\MySQL\MySQL8.0.41\mysql-8.0.41-winx64\mysql-8.0.41-winx64 --datadi…...

Day.js一个2k轻量级的时间日期处理库

dayjs介绍 dayjs是一个极简快速2kB的JavaScript库&#xff0c;可以为浏览器处理解析、验证、操作和显示日期和时间&#xff0c;它的设计目标是提供一个简单、快速且功能强大的日期处理工具&#xff0c;同时保持极小的体积&#xff08;仅 2KB 左右&#xff09;。 Day.js 的 API…...

SQL实战:05之间隔连续数问题求解

概述 最近刷题时遇到一些比较有意思的题目&#xff0c;之前多次遇到一些求解连续数的问题&#xff0c;这次遇到了他们的变种&#xff0c;连续数可以间隔指定的数也视为是一个完整的“连续”。针对连续数的这类问题我们之前讲的可以利用等差数列的思想来解决&#xff0c;然而现…...

Windows下Dify安装及使用

Dify安装及使用 Dify 是开源的 LLM 应用开发平台。提供从 Agent 构建到 AI workflow 编排、RAG 检索、模型管理等能力&#xff0c;轻松构建和运营生成式 AI 原生应用。比 LangChain 更易用。 前置条件 windows下安装了docker环境-Windows11安装Docker-CSDN博客 下载 Git下载…...

回归分析丨基于R语言复杂数据回归与混合效应模型【多水平/分层/嵌套】技术与代码

回归分析是科学研究特别是生态学领域科学研究和数据分析十分重要的统计工具&#xff0c;可以回答众多科学问题&#xff0c;如环境因素对物种、种群、群落及生态系统或气候变化的影响&#xff1b;物种属性和系统发育对物种分布&#xff08;多度&#xff09;的影响等。纵观涉及数…...

EasyRTC嵌入式音视频实时通话SDK技术,打造低延迟、高安全的远程技术支持

一、背景 在当今数字化时代&#xff0c;远程技术支持已成为解决各类技术问题的关键手段。随着企业业务的拓展和技术的日益复杂&#xff0c;快速、高效地解决远程设备与系统的技术难题变得至关重要。EasyRTC作为一款高性能的实时通信解决方案&#xff0c;为远程技术支持提供了创…...

webrtc ICE 打洞总结

要搞清webrtc ICE连接是否能成功 &#xff0c; 主要是搞懂NAT NAT 类型 简单来说 一 是本地的ip和端口 决定外部的 ip和端口(和目的Ip和端口无关) &#xff0c; &#xff08;这种情况又分为 &#xff0c; 无限制&#xff0c;仅限制 ip &#xff0c; 限制ip和port , 也就是…...

AI开发者的Docker实践:汉化(中文),更换镜像源,Dockerfile,部署Python项目

AI开发者的Docker实践&#xff1a;汉化&#xff08;中文&#xff09;&#xff0c;更换镜像源&#xff0c;Dockerfile&#xff0c;部署Python项目 Dcoker官网1、核心概念镜像 (Image)容器 (Container)仓库 (Repository)DockerfileDocker Compose 2、Docker 的核心组件Docker 引擎…...