Java研学-MongoDB(三)

三 文档相关

7 文档统计查询

  ① 语法:

// 精确统计文档数 慢 准
dahuang> db.xiaohuang.countDocuments({条件})
4
// 粗略统计文档数 快 大致准
dahuang> db.xiaohuang.estimatedDocumentCount({条件})
4

  ② 例子:

// 精确统计文档数 name为奔波儿灞
dahuang> db.xiaohuang.countDocuments({name:"奔波儿灞"})
2

8 文档分页查询

  ① 语法:skip() 通常用于跳过前面已经显示过的文档,以便获取后续的文档。limit() 用于指定每页显示的文档数量。

// 第一页(每页10条)
db.xiaohuang.find().limit(10)// 第二页(跳过前10条)
db.xiaohuang.find().skip(10).limit(10)// 第三页
db.xiaohuang.find().skip(20).limit(10)// 对于非常大的集合,skip() 可能会很慢,考虑使用基于游标的分页方法

  ② 例子:

dahuang> db.xiaohuang.find().skip(2).limit(2)
[{_id: ObjectId('6854db7ff50f58c8c26c4bd2'),name: '奔波儿灞',job: 'CEO'},{_id: ObjectId('6854db7ff50f58c8c26c4bd3'),name: '灞波儿奔',job: 'CEO'}
]

9 文档排序查询

  ① 语法:sort()方法用于对查询结果进行排序。可指定一个或多个字段进行排序,并使用 1(升序)或 -1(降序)来定义排序方式。

db.xiaohuang.find().sort({userid: 1})  // 升序
db.xiaohuang.find().sort({userid: -1}) // 降序

  ② 例子:

// 首先对 userid 进行降序排列,然后对 job进行升序排列:
db.xiaohuang.find().sort({userid: -1, job: 1})// 对userid降序排列,跳过前10条记录,然后返回接下来的10条记录
db.xiaohuang.find().sort({userid: -1}).skip(10).limit(10)

  注意:skip() limit() sort()一起执行时,执行顺序为,先sort()后skip()最后limit(),和命令编写顺序无关。

10 文档正则查询

  ① 语法:在//中书写正则表达式即可

db.xiaohuang.find({ field: /正则表达式/ })
// 或
db.xiaohuang.find({ name: { $regex: '奔' } })

  ② 例子:

// i:不区分大小写
// 不区分大小写查询"开水"
db.xiaohuang.find({ name: //i })

11 文档比较查询

  ① 语法:在//中书写正则表达式即可

// 大于
db.xiaohuang.find({ "field": { $gt: value } })  // field > value// 小于
db.xiaohuang.find({ "field": { $lt: value } })  // field < value// 大于等于
db.xiaohuang.find({ "field": { $gte: value } }) // field >= value// 小于等于
db.xiaohuang.find({ "field": { $lte: value } }) // field <= value// 不等于
db.xiaohuang.find({ "field": { $ne: value } })  // field != value

  ② 例子:

// 比较整数时,可以使用 NumberInt(700) 明确指定整数类型
// 查询评论点赞数量大于700的记录
db.xiaohuang.find({ "likenum": { $gt: NumberInt(700) } })

12 文档包含查询

  ① 语法:操作符的值必须是一个数组,即使只有一个元素。

// $in 操作符用于匹配字段值在指定数组中的文档。
db.xiaohuang.find({ userid: { $in: ["10086", "10010"] } })
// $nin 操作符用于匹配字段值不在指定数组中的文档。
db.xiaohuang.find({ userid: { $nin: ["10086", "10010"] } })
// $all:匹配包含数组中所有指定元素的文档。
db.xiaohuang.find({ tags: { $all: ["mongodb", "database"] } })
// $elemMatch:用于匹配数组元素满足多个条件的文档。
db.xiaohuang.find({ scores: { $elemMatch: { $gte: 80, $lt: 85 } } })

13 文档条件连接查询

  ① 语法:操作符的值必须是一个数组,即使只有一个元素。

// $and 操作符用于同时满足多个条件的查询(相当于 SQL 中的 AND)。
// 查询评论集合中 likenum 大于等于 700 并且小于 2000 的文档
db.xiaohuang.find({$and: [{ likenum: { $gte: NumberInt(700) } },{ likenum: { $lt: NumberInt(2000) } }]
})// $or 操作符用于满足任意一个条件的查询(相当于 SQL 中的 OR)。
// 查询评论集合中 userid 为 10010,或者点赞数小于 1000 的文档记录
db.xiaohuang.find({$or: [{ userid: "10010" },{ likenum: { $lt: 1000 } }]
})// MongoDB 会自动将多个条件组合为 $and 查询,因此显式使用 $and 通常是不必要的。
db.xiaohuang.find({likenum: { $gte: NumberInt(700), $lt: NumberInt(2000) }
})// $nor:匹配不满足任何指定条件的文档。
db.xiaohuang.find({$nor: [{ price: 1.99 },{ sale: true }]
})// $not:匹配不满足指定条件的文档。
db.xiaohuang.find({price: { $not: { $gt: 1.99 } }
})

四 索引相关

1 介绍

  在 MongoDB 中,索引是提高查询效率的关键工具。如果没有索引,MongoDB 在处理查询时会进行全集合扫描,就像是在一本厚厚的电话簿中逐页翻找特定信息,这种方式在数据量庞大时效率极低。

  而索引就像电话簿的目录,它以 B-Tree(平衡树)数据结构存储特定字段或一组字段的值,并按这些值排序,使得 MongoDB 可以快速定位到满足查询条件的文档,而无需扫描整个集合,从而显著减少查询时间,特别是在处理大数据集时。索引不仅支持高效的相等匹配,还能优化范围查询(如 >、< 等)和排序操作。

  然而,索引也有其代价,它会占用额外的存储空间,并且在每次插入、更新或删除文档时,MongoDB 都需要更新相应的索引,这可能会略微降低写入操作的性能。因此,在为频繁查询的字段、排序字段或范围查询字段创建索引时,需要权衡查询性能的提升与存储和写入性能的潜在影响。

2 索引类型

  ① 单字段索引:
允许用户在文档的单个字段上创建索引,以支持更高效的查询和排序操作。单字段索引可以是升序(1)或降序(-1),但索引键的排序顺序通常不会对查询性能产生显著影响,因为 MongoDB 可以在任何方向上遍历索引。
例子

// 假设有一个名为 scores 的集合,其中包含以下文档:
{ score: 30 },
{ score: 75 },
{ score: 18 },
{ score: 45 }// 为 score 字段创建一个升序索引(1)或降序(-1)
db.scores.createIndex({ score: 1 })
db.scores.createIndex({ score: -1 })

  ③ 复合索引:
复合索引是 MongoDB 中支持多个字段的索引类型。它允许用户为文档中的多个字段创建一个索引,以提高涉及这些字段的查询性能。复合索引的字段顺序非常重要,因为它决定了索引的排序和使用方式。
例子
复合索引首先按 userid 字段进行升序排序,然后在每个 userid 的值内,再按 score 字段进行降序排序。这意味着索引将优先根据 userid 进行排序和过滤,然后在相同 userid 的文档中根据 score 进行排序。

// 假设有一个名为 scores 的集合,其中包含以下文档:
{ userid: "cxk", score: 30 },
{ userid: "dhh", score: 45 },
{ userid: "cxk", score: 75 },
{ userid: "xyz", score: 55 },
{ userid: "cxk", score: 30 },
{ userid: "xyz", score: 90 }// 为 userid 和 score 字段创建一个复合索引
db.scores.createIndex({ userid: 1, score: -1 })

3 查看索引

  ① 语法:getIndexes()方法可查看集合中所有已创建的索引。该方法会返回一个包含索引信息的数组。

db.xiaohuang.getIndexes()

  ② 例子:

// 每个 MongoDB 集合都会为主键自动创建索引,用于唯一标识每个文档。
dahuang> db.xiaohuang.getIndexes()
[ { v: 2, key: { _id: 1 }, name: '_id_', ns: 'dahuang.xiaohuang' } ]v: 2:表示索引的版本号
key: { _id: 1 }:表示索引的键是 _id 字段,并且是升序排序,默认加的
name: '_id_':索引的名称,默认情况下 _id 字段的索引名称为 _id_
ns: 'dahuang.xiaohuang':表示索引所属(存放)的命名空间,格式为 database.collection,这里是 dahuang.xiaohuang

4 创建索引

  ① 语法:createIndex()为常用查询字段创建索引,可以显著提高查询速度。升序索引,使用 1;对于降序索引,使用 -1。
在大型集合上创建索引会影响性能,尤其是在前台创建索引时。高选择性字段(即字段值唯一性高的字段)更适合作为索引字段。过多的索引会增加存储开销并降低写入性能,需根据查询需求合理设计索引。

db.xiaohuang.createIndex(keys, options)

  ② 参数:为常用查询字段创建索引,可以显著提高查询速度。升序索引,使用 1;对于降序索引,使用 -1。

keys:类型:文档(document)指定索引的字段及其排序方向。升序索引,使用 1;降序索引,使用 -1{ username: 1 }  // 升序索引
{ score: -1 }    // 降序索引
MongoDB 支持多种索引类型,包括单字段索引、复合索引、文本索引、地理空间索引和哈希索引。
options:类型:文档(document)可选参数,用于控制索引的创建行为。常见选项包括:
background:布尔值,表示是否在后台创建索引(默认 false)。
unique:布尔值,表示是否创建唯一索引(默认 false)。
name:字符串,指定索引的名称。
expireAfterSeconds:数值,用于 TTL 索引,指定文档过期时间(以秒为单位)。
sparse:布尔值,表示是否创建稀疏索引(默认 false)。

  ③ 例子:

// 为 username 字段创建升序索引
db.xiaohuang.createIndex({ username: 1 })
// 为 username 升序和 score 降序创建复合索引:
db.xiaohuang.createIndex({ username: 1, score: -1 })
// 为 email 字段创建唯一索引,确保每个 email 值都是唯一的:
db.xiaohuang.createIndex({ email: 1 }, { unique: true })
// 在后台创建索引,以避免阻塞其他操作:
db.xiaohuang.createIndex({ username: 1 }, { background: true })
// 为 createdAt 字段创建 TTL 索引,使文档在 3600 秒(1 小时)后自动删除:
db.xiaohuang.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 })

4 移除索引

  ① 语法:dropIndex()方法可通过索引名称或索引规范文档来指定要删除的索引。

db.xiaohuang.dropIndex(index)

  ② 例子:

// 通过索引规范文档删除索引
// 删除 xiaohuang集合中 job字段上的升序索引:
dahuang> db.xiaohuang.dropIndex({job:1})
// 执行后,MongoDB 会返回一个结果文档,显示删除前集合中的索引数量和操作结果:
{ nIndexesWas: 2, ok: 1 }
// 这表示在删除该索引之前,集合中有 2 个索引,操作成功。
// 通过索引名称删除索引
dahuang> db.xiaohuang.dropIndex("job_1")
{ nIndexesWas: 2, ok: 1 }
// 删除所有索引,id索引不会被删除
dahuang> db.xiaohuang.dropIndexes()

5 索引执行计划

  ① 语法:explain()方法用于分析查询的执行计划,可以查看查询是否使用了索引、查询的执行时间、扫描的文档数量等信息。

// query:查询条件。
// options:可选参数,用于指定查询的选项。
// explain(options):指定 explain 方法的选项,以控制输出的详细程度。通常空着即可
db.xiaohuang.find(query, options).explain(options)

  ② 例子:explain()方法的输出包含多个部分,其中 queryPlanner 是最常用的部分之一。

// 无索引
dahuang> db.xiaohuang.find({name:"奔波儿灞"}).explain()
{queryPlanner: {plannerVersion: 1, // 查询计划的版本。namespace: 'dahuang.xiaohuang', // 查询的集合名称和数据库名称。indexFilterSet: false, // 是否使用了索引过滤器。parsedQuery: { name: { '$eq': '奔波儿灞' } }, // 解析后的查询条件。winningPlan: { // 查询优化器选择的执行计划。stage: 'COLLSCAN', // 扫描方式,例如 COLLSCAN(全集合扫描)或 IXSCAN(索引扫描)。filter: { name: { '$eq': '奔波儿灞' } },direction: 'forward'},rejectedPlans: []},serverInfo: {host: 'MSI',port: 27017,version: '4.0.5',gitVersion: '3739429dd92b92d1b0ab120911a23d50bf03c412'},ok: 1
}
// 有索引
dahuang> db.xiaohuang.find({job:"CEO"}).explain()
{queryPlanner: {plannerVersion: 1,namespace: 'dahuang.xiaohuang',indexFilterSet: false,parsedQuery: { job: { '$eq': 'CEO' } },winningPlan: {stage: 'FETCH', // 抓取,通过IXSCAN获取集合信息,再进行FETCH抓取inputStage: {stage: 'IXSCAN',keyPattern: { job: 1 },indexName: 'job_1',isMultiKey: false,multiKeyPaths: { job: [] },isUnique: false,isSparse: false,isPartial: false,indexVersion: 2,direction: 'forward',indexBounds: { job: [ '["CEO", "CEO"]' ] }}},rejectedPlans: []},serverInfo: {host: 'MSI',port: 27017,version: '4.0.5',gitVersion: '3739429dd92b92d1b0ab120911a23d50bf03c412'},ok: 1
}

6 索引覆盖查询

  ① 介绍:覆盖查询是一种高效的查询类型,它发生在查询条件和投影(返回的字段)都完全由索引字段覆盖的情况下。
这意味着 MongoDB 可以直接从索引中获取所需的数据,而无需访问集合中的实际文档。这种查询方式通常非常高效,因为它避免了文档的读取和内存中的处理。
② 例子

dahuang> db.xiaohuang.find({job:"CEO"},{job:1,_id:0}).explain()
{queryPlanner: {plannerVersion: 1,namespace: 'dahuang.xiaohuang',indexFilterSet: false,parsedQuery: { job: { '$eq': 'CEO' } },winningPlan: {stage: 'PROJECTION',transformBy: { job: 1, _id: 0 },inputStage: {stage: 'IXSCAN',keyPattern: { job: 1 },indexName: 'job_1',isMultiKey: false,multiKeyPaths: { job: [] },isUnique: false,isSparse: false,isPartial: false,indexVersion: 2,direction: 'forward',indexBounds: { job: [ '["CEO", "CEO"]' ] }}},rejectedPlans: []},serverInfo: {host: 'MSI',port: 27017,version: '4.0.5',gitVersion: '3739429dd92b92d1b0ab120911a23d50bf03c412'},ok: 1
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/88240.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/88240.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TCP协议格式与连接释放

TCP报文段格式 TCP虽然是面向字节流的&#xff0c;但TCP传送带数据单元确是报文段。TCP报文段分为首部和数据段部分&#xff0c;而TCP的全部功能体现在它在首部中各字段的作用。因此&#xff0c;只有弄清TCP首部各字段的作用才能掌握TCP的工作原理。 TCP报文段首部的前20字节是…

CSS05:结构伪类选择器和属性选择器

结构伪类选择器 /*ul的第一个子元素*/ ul li:first-child{background: #0af6f6; }/*ul的最后一个子元素*/ ul li:last-child{background: #d27bf3; } /*选中p1&#xff1a;定位到父元素&#xff0c;选择当前的第一个元素 选择当前p元素的父级元素&#xff0c;选中父级元素的第…

使用策略模式 + 自动注册机制来构建旅游点评系统的搜索模块

✅ 目标&#xff1a; 搜索模块支持不同内容类型&#xff08;攻略、达人、游记等&#xff09;每种搜索逻辑用一个策略类表示自动注册&#xff08;基于注解 Spring 容器&#xff09;新增搜索类型时&#xff0c;只需添加一个类 一个注解&#xff0c;无需改工厂、注册表等&#x…

第八十九篇 大数据开发中的数据算法:贪心策略 - 生活中的“精打细算”艺术

在资源有限的世界里&#xff0c;贪心算法教会我们&#xff1a;局部最优的累积&#xff0c;往往是通往全局最高效的捷径。本文通过3个生活化场景原创图表&#xff0c;揭示大数据开发中最实用的优化策略。目录一、贪心算法核心思想&#xff1a;当下即最优二、三大核心应用场景详解…

【论文阅读】Dynamic Few-Shot Visual Learning without Forgetting

系统概述如下: (a) 一个基于卷积神经网络(ConvNet)的识别模型,该模型包含特征提取器和分类器; (b) 一个少样本分类权重生成器。这两个组件都是在一组基础类别上训练的,我们为这些类别准备了大量训练数据。在测试阶段,权重生成器会接收少量新类别的训练数据以及基础类别的…

HTML应用指南:利用GET请求获取全国山姆门店位置信息

山姆会员店作为全球知名的零售品牌&#xff0c;自进入中国市场以来&#xff0c;始终致力于为消费者提供高品质商品与便捷的购物体验。随着新零售业态的快速发展&#xff0c;门店位置信息的获取变得愈发重要。品牌通过不断拓展门店网络&#xff0c;目前已覆盖多个一、二线城市&a…

java ThreadLocal源码分析

写个demo测试下&#xff1a;private static void testThreadLocal() {ThreadLocal<Integer> threadLocal new ThreadLocal<>();new Thread(){Overridepublic void run() {threadLocal.set(9527);System.out.println("curr thread: " Thread.currentThr…

后端Web实战(项目管理)

Restful风格 我们的案例是基于当前最为主流的前后端分离模式进行开发 在前后端分离的开发模式中&#xff0c;前后端开发人员都需要根据提前定义好的接口文档&#xff0c;来进行前后端功能的开发。 后端开发人员&#xff1a;必须严格遵守提供的接口文档进行后端功能开发&#…

Leetcode 3604. Minimum Time to Reach Destination in Directed Graph

Leetcode 3604. Minimum Time to Reach Destination in Directed Graph 1. 解题思路2. 代码实现 题目链接&#xff1a;3604. Minimum Time to Reach Destination in Directed Graph 1. 解题思路 这一题思路上就是一个广度优先遍历&#xff0c;我们不断考察当前时间点以及位置…

OpenXR Runtime切换工具-OpenXR-Runtime-Switcher

在开发VR时&#xff0c;有时有多个设备&#xff0c;大家可能也会选择不同的串流工具&#xff0c;OpenXR类似于默认浏览器&#xff0c;如果设置错误可能导致游戏无法串流。 推荐一个工具&#xff0c;可以设置默认的OpenXR工具。 OpenXR-Runtime-Switcher 对于没有的设备&#…

Opencv探索之旅:从像素变化到世界轮廓的奥秘

在你已经能熟练地为图像施展“降噪”、“缩放”等魔法之后&#xff0c;你的探索之旅来到了一个全新的领域。你可能会好奇&#xff1a;我们人类能轻易地识别出照片中杯子的边缘、建筑的轮廓&#xff0c;那计算机是如何“看见”这些边界的呢&#xff1f;仅仅依靠滤波和颜色变换&a…

Ubuntu 22.04 + MySQL 8 无密码登录问题与 root 密码重置指南

背景场景 在 Ubuntu 系统中使用 apt 或 deb 包方式安装 MySQL 8 时&#xff1a; 初次安装后会自动初始化数据库&#xff1b;但 没有提示 root 初始密码&#xff1b;导致 mysql -u root -p 无法登录。 为了解决该问题&#xff0c;通常我们使用 --skip-grant-tables 方式跳过权限…

题解:P13017 [GESP202506 七级] 线图

首先明白定义&#xff1a; 线图 L(G)L(G)L(G) 的顶点对应原图 GGG 的边&#xff0c;当且仅当原图中的两条边有公共顶点时&#xff0c;对应的线图顶点之间有一条边。 不难想到&#xff0c;对于原图中的每个顶点 vvv&#xff0c;其度数 d(v)d(v)d(v) 对应的边集可以形成 (d(v)2)\…

c++ duiLib环境集成2

继续上一篇&#xff0c;现在需要把控制台隐藏&#xff0c;只显示调用duiLib框架显示的窗口。右键项目 → 属性 → 链接器 → 系统 → ‌子系统‌改为 窗口(/SUBSYSTEM:WINDOWS)。原来是这样&#xff1a;修改为&#xff1a;运行报错&#xff1a;需要修改入口函数为WinMain。如下…

常见的网络攻击方式及防御措施

常见的网络攻击方式及防御措施&#xff1a;全面解析网络安全威胁 前言肝文不易&#xff0c;点个免费的赞和关注&#xff0c;有错误的地方请指出&#xff0c;看个人主页有惊喜。 作者&#xff1a;神的孩子都在歌唱在信息化高速发展的今天&#xff0c;网络安全威胁无处不在&#…

JavaScript 中导入模块时,确实不需要显式地写 node_modules 路径。

1. 正确的导入语法在 Webpack、Vite 等打包工具中&#xff0c;node_modules 目录是默认的模块搜索路径&#xff0c;因此直接写包名即可&#xff1a;// ✅ 正确&#xff1a;直接使用包名import nprogress/nprogress.css;// ❌ 错误&#xff1a;不需要显式写 node_modules 路径im…

ELK Stack技术栈

文章目录一、日志收集所解决的问题二、Elastic Stack 组件介绍2.1 Elasticsearch2.2 Logstash2.3 Kibana2.4 Filebeat beats三、ELK Stack集群安装3.1 安装JAVA环境&#xff08;所有ES节点&#xff09;3.2 安装ES集群3.2.1 ES单节点部署3.2.2 ES JAVA调优&#xff1a;堆(heap)内…

大腾智能国产 3D CAD:设计自由度拉满,数据安全锁死

在智能制造与数字化转型的浪潮中&#xff0c;大腾智能CAD作为一款自主研发的三维计算机辅助设计软件&#xff0c;凭借其从概念设计到制造落地的全流程覆盖能力&#xff0c;正成为国产工业设计软件领域的新锐力量。软件深度融合先进建模技术与工程实践需求&#xff0c;为机械制造…

ubuntu 操作记录

1&#xff1a;安装minicom 1: sudo apt-get install minicom minicom -s 2&#xff1a;Ctrl Z C 的区别 ctrlz的是将任务中断,但是此任务并没有结束,他仍然在进程中他只是维持挂起的状态,用户可以使用fg/bg操作继续前台或后台的任务,fg命令重新启动前台被中断的任务,bg命令…

深度剖析:向70岁老系统植入通信芯片——MCP注入构建未来级分布式通信

> 如何让老旧系统重获新生?协议注入技术是关键。 ## 一、当遗留系统遇上分布式未来:一场艰难的对话 想象一下:你负责维护一套诞生于20年前的单体式银行核心系统,它像一位固执的70岁老人,使用着陈旧的TCP自定义协议。这时业务部门要求实现与云原生风险分析引擎的实时…