MongoDB基础操作
<p></p><div class="toc"><div class="toc-container-header">目录</div><ul><li>一、什么是MongoDB</li><li>二、MongoDB 与关系型数据库对比</li><li>三、数据类型</li><li>四、部署MongoDB<ul><li>1、下载二进制包</li><li>2、下载安装包并解压</li><li>3、创建用于存放数据和日志的目录,并修改权限</li><li>4、启动MongoDB<ul><li>4.1前台启动</li><li>4.2后台启动</li><li>4.3、配置文件启动服务</li><li>4.4、配置systemd服务</li><li>4.5、systemctl启动MongoDB</li></ul></li><li>5、客户端配置</li><li>6、关闭MongoDB<ul><li>6.1、前台启动</li><li>6.2、后台启动</li><li>6.3、kill命令关闭</li><li>6.4、MongoDB函数关闭</li></ul></li></ul></li><li>五、MongoDB基本操作及增删改查<ul><li>1、基本操作<ul><li>1.1、登录数据库</li><li>1.2、查看数据库</li><li>1.3、查看当前正在使用的数据库</li><li>1.4、选择/创建数据库</li><li>1.5、查看集合</li><li>1.6、创建集合</li><li>1.7、删除集合</li><li>1.8、删除数据库</li></ul></li><li>2、增删改查<ul><li>2.1、插入文档<ul><li>2.1.1、一次性插入多条数据</li></ul></li><li>2.2、查询文档<ul><li>2.2.1、查询集合内所有的记录数</li></ul></li><li>2.3、修改文档</li><li>2.4、删除文档</li></ul></li></ul></li><li>六、MongoDB支持存储的数据类型<ul><li>1、数字</li><li>2、字符串</li><li>3、正则表达式</li><li>4、数组</li><li>5、日期</li><li>6、内嵌文档</li></ul></li><li>七、MongoDB中的索引<ul><li>1、查看索引</li><li>2、需要索引的查询场景<ul><li>2.1、创建有10000个文档的集合</li><li>2.2、查询<code>age</code>为<code>200</code>的文档</li><li>2.3、添加<code>limit</code>查询文档</li><li>2.4、创建索引</li><li>2.5、自定义索引名字</li></ul></li><li>3、查看索引的大小</li><li>4、删除索引<ul><li>4.1、按名称删除索引</li><li>4.2、删除所有的索引</li></ul></li><li>5、优缺点<ul><li>5.1、优点:</li><li>5.2、缺点:</li></ul></li></ul></li></ul></div><p></p><h2 id="一什么是mongodb">一、什么是MongoDB</h2>
<p><code>MongoDB</code> 是一个开源、高性能、无模式的、基于分布式文件存储的文档型数据库,当初的设计就是用于简化开发和方便扩展,是 <code>NoSQL</code> 数据库产品中的一种。是最像关系型数据库(<code>MySQL</code>)的非关系型数据库。</p>
<p>它支持的数据结构非常松散,是一种类似于<code>JSON</code>的格式叫<code>BSON(Binary JSON)</code>,所以它既可以存储比较复杂的数据类型,又相当的灵活。</p>
<h2 id="二mongodb-与关系型数据库对比">二、MongoDB 与关系型数据库对比</h2>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104059043-1356135094.webp" alt="webp" loading="lazy"></p>
<table>
<thead>
<tr>
<th style="text-align: center">SQL 术语/概念</th>
<th style="text-align: center">MongoDB 术语/概念</th>
<th style="text-align: center">解释说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">database</td>
<td style="text-align: center">database</td>
<td style="text-align: center">数据库</td>
</tr>
<tr>
<td style="text-align: center">table</td>
<td style="text-align: center">collection</td>
<td style="text-align: center">数据库表/集合</td>
</tr>
<tr>
<td style="text-align: center">row</td>
<td style="text-align: center">document</td>
<td style="text-align: center">数据记录行/文档</td>
</tr>
<tr>
<td style="text-align: center">column</td>
<td style="text-align: center">field</td>
<td style="text-align: center">数据字段/域</td>
</tr>
<tr>
<td style="text-align: center">index</td>
<td style="text-align: center">index</td>
<td style="text-align: center">索引</td>
</tr>
<tr>
<td style="text-align: center">table joins</td>
<td style="text-align: center">不支持</td>
<td style="text-align: center">表连接,MongoDB 不支持</td>
</tr>
<tr>
<td style="text-align: center">不支持</td>
<td style="text-align: center">嵌入文档</td>
<td style="text-align: center">MongoDB 通过嵌入式文档来替代多表连接</td>
</tr>
<tr>
<td style="text-align: center">primary key</td>
<td style="text-align: center">primary key</td>
<td style="text-align: center">主键,MongoDB 自动将_id 字段设置为主键</td>
</tr>
</tbody>
</table>
<h2 id="三数据类型">三、数据类型</h2>
<table>
<thead>
<tr>
<th style="text-align: center">数据类型</th>
<th style="text-align: center">描述</th>
<th style="text-align: center">举例</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">字符串</td>
<td style="text-align: center">utf8字符串都可以表示为字符串类型的数据</td>
<td style="text-align: center"></td>
</tr>
<tr>
<td style="text-align: center">对象id</td>
<td style="text-align: center">对象id是文档的12字节的唯一ID</td>
<td style="text-align: center"></td>
</tr>
<tr>
<td style="text-align: center">布尔值</td>
<td style="text-align: center">真或者假:true或者false</td>
<td style="text-align: center"></td>
</tr>
<tr>
<td style="text-align: center">数组</td>
<td style="text-align: center">值的集合或者列表都可以表示成数组</td>
<td style="text-align: center"></td>
</tr>
<tr>
<td style="text-align: center">整数</td>
<td style="text-align: center">(Int32 Int64 你们就知道有个Int就行了,一般我们用Int32)</td>
<td style="text-align: center"></td>
</tr>
<tr>
<td style="text-align: center">null</td>
<td style="text-align: center">表示空值或者未定义的对象</td>
<td style="text-align: center"></td>
</tr>
<tr>
<td style="text-align: center">undefined</td>
<td style="text-align: center">文档中也可以使用未定义类型</td>
<td style="text-align: center"></td>
</tr>
</tbody>
</table>
<h2 id="四部署mongodb">四、部署MongoDB</h2>
<h3 id="1下载二进制包">1、下载二进制包</h3>
<p>下载地址</p>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104058673-1661760903.png" alt="image-20240424165506053" loading="lazy"></p>
<h3 id="2下载安装包并解压">2、下载安装包并解压</h3>
<pre><code class="language-bash">wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.6.tgz
tar xzvf mongodb-linux-x86_64-rhel70-4.4.6.tgz -C /usr/local
cd /usr/local/
ln -s /usr/local/mongodb-linux-x86_64-rhel70-4.4.6 /usr/local/mongodb
</code></pre>
<h3 id="3创建用于存放数据和日志的目录并修改权限">3、创建用于存放数据和日志的目录,并修改权限</h3>
<pre><code class="language-bash"># 创建存放数据的目录
mkdir -p /usr/local/mongodb/data/db
# 创建存放日志的目录
mkdir -p /usr/local/mongodb/logs
# 创建日志记录文件
touch /usr/local/mongodb/logs/mongodb.log
</code></pre>
<h3 id="4启动mongodb">4、启动MongoDB</h3>
<h4 id="41前台启动">4.1前台启动</h4>
<blockquote>
<p>MongoDB的默认启动方式为前台启动</p>
</blockquote>
<pre><code class="language-bash">cd /usr/local/mongodb/
bin/mongod \
--dbpath /usr/local/mongodb/data/db/ \
--logpath /usr/local/mongodb/logs/mongodb.log \
--logappend \
--port 27017 \
--bind_ip 0.0.0.0
</code></pre>
<blockquote>
<p>参数解释:</p>
</blockquote>
<pre><code class="language-bash"> --dbpath:指定数据文件存放目录
--logpath:指定日志文件,注意是指定文件不是目录
--logappend:使用追加的方式记录日志
--port:指定端口,默认为 27017
--bind_ip:绑定服务 IP,若绑定 127.0.0.1,则只能本机访问,默认为本机地址
</code></pre>
<h4 id="42后台启动">4.2后台启动</h4>
<blockquote>
<p>后台启动在命令中添加--fork即可</p>
</blockquote>
<pre><code class="language-bash">cd /usr/local/mongodb/
bin/mongod \
--dbpath /usr/local/mongodb/data/db/ \
--logpath /usr/local/mongodb/logs/mongodb.log \
--logappend \
--port 27017 \
--bind_ip 0.0.0.0 \
--fork
</code></pre>
<h4 id="43配置文件启动服务">4.3、配置文件启动服务</h4>
<blockquote>
<p>bin目录下增加一个mongodb.conf配置文件</p>
</blockquote>
<pre><code class="language-bash">vim /usr/local/mongodb/bin/mongodb.conf
# 数据文件存放目录
dbpath = /usr/local/mongodb/data/db
# 日志文件存放目录
logpath = /usr/local/mongodb/logs/mongodb.log
# 以追加的方式记录日志
logappend = true
# 端口默认为 27017
port = 27017
# 对访问 IP 地址不做限制,默认为本机地址
bind_ip = 0.0.0.0
# 以守护进程的方式启用,即在后台运行
fork = true
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104058361-1220371782.png" alt="image-20240424171746978" loading="lazy"></p>
<blockquote>
<p>启动命令:</p>
</blockquote>
<pre><code class="language-bash">bin/mongod -f /usr/local/mongodb/bin/mongodb.conf
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104057999-1870367086.png" alt="image-20240424172044021" loading="lazy"></p>
<h4 id="44配置systemd服务">4.4、配置systemd服务</h4>
<pre><code class="language-bash">vim /usr/lib/systemd/system/mongodb.service
Description=mongodb
After=network.target remote-fs.target nss-lookup.target
Type=forking
ExecStart=/usr/local/mongodb/bin/mongod --config /usr/local/mongodb/bin/mongodb.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/usr/local/mongodb/bin/mongod --shutdown --config /usr/local/mongodb/bin/mongodb.conf
PrivateTmp=true
WantedBy=multi-user.target
chmod 754 /usr/lib/systemd/system/mongodb.service
</code></pre>
<h4 id="45systemctl启动mongodb">4.5、systemctl启动MongoDB</h4>
<pre><code class="language-bash">systemctl start mongodb
</code></pre>
<h3 id="5客户端配置">5、客户端配置</h3>
<blockquote>
<p>添加环境变量</p>
</blockquote>
<pre><code class="language-bash">echo "export PATH=/usr/local/mongodb/bin/:$PATH" >> /etc/profile
source /etc/profile
mongo
</code></pre>
<h3 id="6关闭mongodb">6、关闭MongoDB</h3>
<h4 id="61前台启动">6.1、前台启动</h4>
<pre><code class="language-bash">Ctrl + c
</code></pre>
<h4 id="62后台启动">6.2、后台启动</h4>
<pre><code class="language-bash"># 命令启动方式的关闭
bin/mongod --dbpath /usr/local/mongodb/data/db/ --logpath /usr/local/mongodb/logs/mongodb.log --logappend --port 27017 --bind_ip 0.0.0.0 --fork --shutdown
# 配置文件启动方式的关闭
bin/mongod -f /usr/local/mongodb/bin/mongodb.conf --shutdown
</code></pre>
<h4 id="63kill命令关闭">6.3、kill命令关闭</h4>
<blockquote>
<p>不推荐使用</p>
</blockquote>
<pre><code class="language-bash"># 查看 mongodb 运行的进程信息
ps -ef | grep mongodb
# kill -9 强制关闭
kill -9 pid
</code></pre>
<h4 id="64mongodb函数关闭">6.4、MongoDB函数关闭</h4>
<pre><code class="language-bash"># 连接 mongodb
mongo
# 切换 admin 数据库
use admin
# 执行以下函数(2选1)即可关闭服务
db.shutdownServer()
db.runCommand("shutdown")
</code></pre>
<h2 id="五mongodb基本操作及增删改查">五、MongoDB基本操作及增删改查</h2>
<h3 id="1基本操作">1、基本操作</h3>
<h4 id="11登录数据库">1.1、登录数据库</h4>
<pre><code class="language-bash">mongo
</code></pre>
<h4 id="12查看数据库">1.2、查看数据库</h4>
<pre><code class="language-bash">show databases
show dbs
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104057668-1682239604.png" alt="image-20240424183039764" loading="lazy"></p>
<h4 id="13查看当前正在使用的数据库">1.3、查看当前正在使用的数据库</h4>
<pre><code class="language-bash">db
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104057330-347805294.png" alt="image-20240425115609645" loading="lazy"></p>
<h4 id="14选择创建数据库">1.4、选择/创建数据库</h4>
<pre><code class="language-bash">use admin
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104057019-336985668.png" alt="image-20240425114338328" loading="lazy"></p>
<blockquote>
<p>如果切换到一个没有的数据库,那么会隐式创建这个数据库。(后期当该数据库有数据时,系统自动创建)</p>
</blockquote>
<pre><code class="language-bash">use admin1
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104056724-2136159197.png" alt="image-20240425114612080" loading="lazy"></p>
<h4 id="15查看集合">1.5、查看集合</h4>
<pre><code class="language-bash">show collections
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104056357-279768021.png" alt="image-20240425114752959" loading="lazy"></p>
<h4 id="16创建集合">1.6、创建集合</h4>
<pre><code class="language-bash">db.createCollection('集合名')
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104055995-1835413024.png" alt="image-20240425115030221" loading="lazy"></p>
<h4 id="17删除集合">1.7、删除集合</h4>
<pre><code class="language-bash">db.集合名.drop()
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104055627-1872675130.png" alt="image-20240425115744209" loading="lazy"></p>
<h4 id="18删除数据库">1.8、删除数据库</h4>
<blockquote>
<p>通过<code>use</code>语法选择数据<br>
通过<code>db.dropDataBase()</code>删除数据库</p>
</blockquote>
<pre><code class="language-bash">> use admin1
switched to db admin1
> show collections
c2
> db.dropDatabase()
{ "dropped" : "admin1", "ok" : 1 }
> show dbs
admin 0.000GB
config0.000GB
local 0.000GB
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104055299-815479346.png" alt="image-20240425120604758" loading="lazy"></p>
<h3 id="2增删改查">2、增删改查</h3>
<h4 id="21插入文档">2.1、插入文档</h4>
<blockquote>
<p>如果集合存在,那么直接插入数据。</p>
<p>如果集合不存在,那么会隐式创建。</p>
</blockquote>
<pre><code class="language-bash">db.集合名.insert(JSON数据)
</code></pre>
<ul>
<li>在test1数据库的c1集合中插入文档,(姓名:张三,年龄:18)</li>
</ul>
<pre><code class="language-bash">> use test1
switched to db test1
> show collections
> db.createCollection('c1')
{ "ok" : 1 }
> db.c1.insert({name:"张三",age:18})
WriteResult({ "nInserted" : 1 })
> db.c1.find()
{ "_id" : ObjectId("6629dc959117871a1f5ab723"), "name" : "张三", "age" : 18 }
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104054846-1060307383.png" alt="image-20240425125211753" loading="lazy"></p>
<ul>
<li>数据库和集合不存在都隐式创建</li>
<li>对象的键统一不加引号(方便看),但是查看集合数据时系统会自动加</li>
<li><code>mongodb</code>会给每条数据增加一个全球唯一的<code>_id</code>键</li>
</ul>
<h5 id="211一次性插入多条数据">2.1.1、一次性插入多条数据</h5>
<ul>
<li>数组中一个个写入<code>json</code>数据</li>
</ul>
<pre><code class="language-bash">> db.c1.insert([{name:"李四",age:20},{name:"王五",age:21},{name:"赵六",age:22}])
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 3,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
> db.c1.find()
{ "_id" : ObjectId("6629dc959117871a1f5ab723"), "name" : "张三", "age" : 18 }
{ "_id" : ObjectId("6629de189117871a1f5ab724"), "name" : "李四", "age" : 20 }
{ "_id" : ObjectId("6629de189117871a1f5ab725"), "name" : "王五", "age" : 21 }
{ "_id" : ObjectId("6629de189117871a1f5ab726"), "name" : "赵六", "age" : 22 }
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104054397-168300273.png" alt="image-20240425125249398" loading="lazy"></p>
<ul>
<li>写for循环插入数据</li>
</ul>
<pre><code class="language-bash">> for (var i=1;i<=10;i++) {db.c1.insert({name:"a"+i , age: i}) }
WriteResult({ "nInserted" : 1 })
> db.c1.find()
{ "_id" : ObjectId("6629dc959117871a1f5ab723"), "name" : "张三", "age" : 18 }
{ "_id" : ObjectId("6629de189117871a1f5ab724"), "name" : "李四", "age" : 20 }
{ "_id" : ObjectId("6629de189117871a1f5ab725"), "name" : "王五", "age" : 21 }
{ "_id" : ObjectId("6629de189117871a1f5ab726"), "name" : "赵六", "age" : 22 }
{ "_id" : ObjectId("6629def99117871a1f5ab727"), "name" : "a1", "age" : 1 }
{ "_id" : ObjectId("6629def99117871a1f5ab728"), "name" : "a2", "age" : 2 }
{ "_id" : ObjectId("6629def99117871a1f5ab729"), "name" : "a3", "age" : 3 }
{ "_id" : ObjectId("6629def99117871a1f5ab72a"), "name" : "a4", "age" : 4 }
{ "_id" : ObjectId("6629def99117871a1f5ab72b"), "name" : "a5", "age" : 5 }
{ "_id" : ObjectId("6629def99117871a1f5ab72c"), "name" : "a6", "age" : 6 }
{ "_id" : ObjectId("6629def99117871a1f5ab72d"), "name" : "a7", "age" : 7 }
{ "_id" : ObjectId("6629def99117871a1f5ab72e"), "name" : "a8", "age" : 8 }
{ "_id" : ObjectId("6629def99117871a1f5ab72f"), "name" : "a9", "age" : 9 }
{ "_id" : ObjectId("6629def99117871a1f5ab730"), "name" : "a10", "age" : 10 }
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104054043-143424885.png" alt="image-20240425125400607" loading="lazy"></p>
<h4 id="22查询文档">2.2、查询文档</h4>
<pre><code class="language-bash">db.集合名.find(条件[,查询的列])
</code></pre>
<table>
<thead>
<tr>
<th style="text-align: center">条件</th>
<th style="text-align: center">写法</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">查询所有的数据</td>
<td style="text-align: center">{}或者不写</td>
</tr>
<tr>
<td style="text-align: center">查询age=6的数据</td>
<td style="text-align: center"></td>
</tr>
<tr>
<td style="text-align: center">既要age=6又要性别=男</td>
<td style="text-align: center"></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th style="text-align: center">查询的列(可选参数)</th>
<th style="text-align: center">写法</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">查询全部列(字段)</td>
<td style="text-align: center">不写</td>
</tr>
<tr>
<td style="text-align: center">只显示age列(字段)</td>
<td style="text-align: center"></td>
</tr>
<tr>
<td style="text-align: center">除了age列(字段)都显示</td>
<td style="text-align: center"></td>
</tr>
</tbody>
</table>
<blockquote>
<p>其他语法</p>
</blockquote>
<pre><code class="language-bash">db.集合名.find({
键:{运算符:值}
})
</code></pre>
<table>
<thead>
<tr>
<th>运算符</th>
<th>作用</th>
</tr>
</thead>
<tbody>
<tr>
<td>$gt</td>
<td>大于</td>
</tr>
<tr>
<td>$gte</td>
<td>大于等于</td>
</tr>
<tr>
<td>$lt</td>
<td>小于</td>
</tr>
<tr>
<td>$lte</td>
<td>小于等于</td>
</tr>
<tr>
<td>$ne</td>
<td>不等于</td>
</tr>
<tr>
<td>$in</td>
<td>in</td>
</tr>
<tr>
<td>$nin</td>
<td>not in</td>
</tr>
</tbody>
</table>
<ul>
<li>查看所有数据</li>
</ul>
<pre><code class="language-bash">> db.c1.find()
{ "_id" : ObjectId("6629dc959117871a1f5ab723"), "name" : "张三", "age" : 18 }
{ "_id" : ObjectId("6629de189117871a1f5ab724"), "name" : "李四", "age" : 20 }
{ "_id" : ObjectId("6629de189117871a1f5ab725"), "name" : "王五", "age" : 21 }
{ "_id" : ObjectId("6629de189117871a1f5ab726"), "name" : "赵六", "age" : 22 }
{ "_id" : ObjectId("6629def99117871a1f5ab727"), "name" : "a1", "age" : 1 }
{ "_id" : ObjectId("6629def99117871a1f5ab728"), "name" : "a2", "age" : 2 }
{ "_id" : ObjectId("6629def99117871a1f5ab729"), "name" : "a3", "age" : 3 }
{ "_id" : ObjectId("6629def99117871a1f5ab72a"), "name" : "a4", "age" : 4 }
{ "_id" : ObjectId("6629def99117871a1f5ab72b"), "name" : "a5", "age" : 5 }
{ "_id" : ObjectId("6629def99117871a1f5ab72c"), "name" : "a6", "age" : 6 }
{ "_id" : ObjectId("6629def99117871a1f5ab72d"), "name" : "a7", "age" : 7 }
{ "_id" : ObjectId("6629def99117871a1f5ab72e"), "name" : "a8", "age" : 8 }
{ "_id" : ObjectId("6629def99117871a1f5ab72f"), "name" : "a9", "age" : 9 }
{ "_id" : ObjectId("6629def99117871a1f5ab730"), "name" : "a10", "age" : 10 }
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104053640-874303916.png" alt="image-20240425125449664" loading="lazy"></p>
<ul>
<li>只看name列</li>
</ul>
<pre><code class="language-bash">> db.c1.find({},{name:1})
{ "_id" : ObjectId("6629dc959117871a1f5ab723"), "name" : "张三" }
{ "_id" : ObjectId("6629de189117871a1f5ab724"), "name" : "李四" }
{ "_id" : ObjectId("6629de189117871a1f5ab725"), "name" : "王五" }
{ "_id" : ObjectId("6629de189117871a1f5ab726"), "name" : "赵六" }
{ "_id" : ObjectId("6629def99117871a1f5ab727"), "name" : "a1" }
{ "_id" : ObjectId("6629def99117871a1f5ab728"), "name" : "a2" }
{ "_id" : ObjectId("6629def99117871a1f5ab729"), "name" : "a3" }
{ "_id" : ObjectId("6629def99117871a1f5ab72a"), "name" : "a4" }
{ "_id" : ObjectId("6629def99117871a1f5ab72b"), "name" : "a5" }
{ "_id" : ObjectId("6629def99117871a1f5ab72c"), "name" : "a6" }
{ "_id" : ObjectId("6629def99117871a1f5ab72d"), "name" : "a7" }
{ "_id" : ObjectId("6629def99117871a1f5ab72e"), "name" : "a8" }
{ "_id" : ObjectId("6629def99117871a1f5ab72f"), "name" : "a9" }
{ "_id" : ObjectId("6629def99117871a1f5ab730"), "name" : "a10" }
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104053255-2076143011.png" alt="image-20240425125526995" loading="lazy"></p>
<ul>
<li>查看除了name列</li>
</ul>
<pre><code class="language-bash">> db.c1.find({},{name:0})
{ "_id" : ObjectId("6629dc959117871a1f5ab723"), "age" : 18 }
{ "_id" : ObjectId("6629de189117871a1f5ab724"), "age" : 20 }
{ "_id" : ObjectId("6629de189117871a1f5ab725"), "age" : 21 }
{ "_id" : ObjectId("6629de189117871a1f5ab726"), "age" : 22 }
{ "_id" : ObjectId("6629def99117871a1f5ab727"), "age" : 1 }
{ "_id" : ObjectId("6629def99117871a1f5ab728"), "age" : 2 }
{ "_id" : ObjectId("6629def99117871a1f5ab729"), "age" : 3 }
{ "_id" : ObjectId("6629def99117871a1f5ab72a"), "age" : 4 }
{ "_id" : ObjectId("6629def99117871a1f5ab72b"), "age" : 5 }
{ "_id" : ObjectId("6629def99117871a1f5ab72c"), "age" : 6 }
{ "_id" : ObjectId("6629def99117871a1f5ab72d"), "age" : 7 }
{ "_id" : ObjectId("6629def99117871a1f5ab72e"), "age" : 8 }
{ "_id" : ObjectId("6629def99117871a1f5ab72f"), "age" : 9 }
{ "_id" : ObjectId("6629def99117871a1f5ab730"), "age" : 10 }
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104052885-1894399460.png" alt="image-20240425125554132" loading="lazy"></p>
<ul>
<li>查询<code>age</code>大于<code>6</code>的数据</li>
</ul>
<pre><code class="language-bash">> db.c1.find({age:{$gt:6}})
{ "_id" : ObjectId("6629dc959117871a1f5ab723"), "name" : "张三", "age" : 18 }
{ "_id" : ObjectId("6629de189117871a1f5ab724"), "name" : "李四", "age" : 20 }
{ "_id" : ObjectId("6629de189117871a1f5ab725"), "name" : "王五", "age" : 21 }
{ "_id" : ObjectId("6629de189117871a1f5ab726"), "name" : "赵六", "age" : 22 }
{ "_id" : ObjectId("6629def99117871a1f5ab72d"), "name" : "a7", "age" : 7 }
{ "_id" : ObjectId("6629def99117871a1f5ab72e"), "name" : "a8", "age" : 8 }
{ "_id" : ObjectId("6629def99117871a1f5ab72f"), "name" : "a9", "age" : 9 }
{ "_id" : ObjectId("6629def99117871a1f5ab730"), "name" : "a10", "age" : 10 }
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104052532-256858547.png" alt="image-20240425125634325" loading="lazy"></p>
<ul>
<li>查询年龄为<code>7</code>岁、<code>10</code>岁、<code>18</code>岁的数据</li>
</ul>
<pre><code class="language-bash">> db.c1.find({age:{$in:}})
{ "_id" : ObjectId("6629dc959117871a1f5ab723"), "name" : "张三", "age" : 18 }
{ "_id" : ObjectId("6629def99117871a1f5ab72d"), "name" : "a7", "age" : 7 }
{ "_id" : ObjectId("6629def99117871a1f5ab730"), "name" : "a10", "age" : 10 }
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104052154-1016607317.png" alt="image-20240425142853007" loading="lazy"></p>
<h5 id="221查询集合内所有的记录数">2.2.1、查询集合内所有的记录数</h5>
<pre><code class="language-bash">db.集合名.count()
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104051814-1243070532.png" alt="image-20240425205417337" loading="lazy"></p>
<h4 id="23修改文档">2.3、修改文档</h4>
<pre><code class="language-bash">db.集合名.update(
<filter>, // 查询条件(筛选待更新的文档)
<update>, // 更新操作定义(如何修改文档)
{
upsert: <boolean>,// 可选,如果无匹配文档则插入,默认为 false
multi: <boolean>, // 可选,是否更新所有匹配的文档,默认为 false(仅更新第一条)
collation: <object>, // 可选,指定比较选项(如大小写敏感等)
arrayFilters: <array>, // 可选,用于处理嵌套数组中的条件匹配
hint: <string|document>, // 可选,提供索引来指导查询
writeConcern: <document>, // 可选,指定写关注级别
let: <object> // 可选,用于与聚合管道更新相关的变量定义
}
)
</code></pre>
<ul>
<li>将<code>{name:"张三"}</code>修改为<code>{name:"zhangsan"}</code></li>
</ul>
<pre><code class="language-bash">> db.c1.update({name:"张三"},{$set:{name:"zhangsan"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c1.find()
{ "_id" : ObjectId("6629dc959117871a1f5ab723"), "name" : "zhangsan", "age" : 18 }
{ "_id" : ObjectId("6629de189117871a1f5ab724"), "name" : "李四", "age" : 20 }
{ "_id" : ObjectId("6629de189117871a1f5ab725"), "name" : "王五", "age" : 21 }
{ "_id" : ObjectId("6629de189117871a1f5ab726"), "name" : "赵六", "age" : 22 }
{ "_id" : ObjectId("6629def99117871a1f5ab727"), "name" : "a1", "age" : 1 }
{ "_id" : ObjectId("6629def99117871a1f5ab728"), "name" : "a2", "age" : 2 }
{ "_id" : ObjectId("6629def99117871a1f5ab729"), "name" : "a3", "age" : 3 }
{ "_id" : ObjectId("6629def99117871a1f5ab72a"), "name" : "a4", "age" : 4 }
{ "_id" : ObjectId("6629def99117871a1f5ab72b"), "name" : "a5", "age" : 5 }
{ "_id" : ObjectId("6629def99117871a1f5ab72c"), "name" : "a6", "age" : 6 }
{ "_id" : ObjectId("6629def99117871a1f5ab72d"), "name" : "a7", "age" : 7 }
{ "_id" : ObjectId("6629def99117871a1f5ab72e"), "name" : "a8", "age" : 8 }
{ "_id" : ObjectId("6629def99117871a1f5ab72f"), "name" : "a9", "age" : 9 }
{ "_id" : ObjectId("6629def99117871a1f5ab730"), "name" : "a10", "age" : 10 }
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104051434-1596259553.png" alt="image-20240425184009386" loading="lazy"></p>
<ul>
<li>将<code>{name:"李四"}</code>的年龄加/减<code>5</code></li>
</ul>
<blockquote>
<p>年龄加5</p>
</blockquote>
<pre><code class="language-bash">db.c1.update({name:"李四"},{$inc:{age:5}})
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104051024-1346838073.png" alt="image-20240425184419154" loading="lazy"></p>
<blockquote>
<p>年龄减5</p>
</blockquote>
<pre><code class="language-bash">db.c1.update({name:"李四"},{$inc:{age:-5}})
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104050577-2130340096.png" alt="image-20240425184616300" loading="lazy"></p>
<h4 id="24删除文档">2.4、删除文档</h4>
<pre><code class="language-bash">db.集合名.remove(条件[,是否删除一条])
</code></pre>
<ul>
<li>
<p>删除一条数据</p>
<ul>
<li>
<pre><code class="language-bash">db.c1.remove({},true)
</code></pre>
<blockquote>
<p>默认删除的第一条数据</p>
</blockquote>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104050210-1122522488.png" alt="image-20240425204653851" loading="lazy"></p>
</li>
<li>
<pre><code class="language-bash">db.c1.remove({name:"李四"})
</code></pre>
<blockquote>
<p>删除指定数据</p>
</blockquote>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104049675-1487282007.png" alt="image-20240425204856853" loading="lazy"></p>
</li>
</ul>
</li>
</ul>
<h2 id="六mongodb支持存储的数据类型">六、MongoDB支持存储的数据类型</h2>
<h3 id="1数字">1、数字</h3>
<ul>
<li><code>shell</code>默认使用<code>64</code>位浮点型数值</li>
</ul>
<pre><code class="language-bash">db.b1.insert({x:3.1415926})
db.b1.insert({x:3})
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104049316-2090052594.png" alt="image-20240425213512686" loading="lazy"></p>
<ul>
<li>整型值,可以用<code>NumberInt</code>或者<code>NumberLong</code>表示</li>
</ul>
<pre><code class="language-bash">db.b1.insert({x:NumberInt(10)})
db.b1.insert({x:NumberLong(12)})
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104048974-294051233.png" alt="image-20240425213843340" loading="lazy"></p>
<h3 id="2字符串">2、字符串</h3>
<pre><code class="language-bash">db.b1.insert({x:"hello MongoDB!"})
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104048645-325142624.png" alt="image-20240425214353152" loading="lazy"></p>
<h3 id="3正则表达式">3、正则表达式</h3>
<blockquote>
<p>查询所有<code>key</code>为<code>x</code>,<code>value</code>以<code>hello</code>开头的文档且不区分大小写</p>
</blockquote>
<pre><code class="language-bash">db.b1.find({x:/^(hello).(.)+/i})
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104048310-751287196.png" alt="image-20240425214936289" loading="lazy"></p>
<h3 id="4数组">4、数组</h3>
<blockquote>
<p>数组中的数据类型可以是多种多样的</p>
</blockquote>
<pre><code class="language-bash">db.b1.insert({x:})
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104047943-337508846.png" alt="image-20240425215940415" loading="lazy"></p>
<h3 id="5日期">5、日期</h3>
<pre><code class="language-bash">db.b1.insert({x:new Date()})
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104047560-1380700557.png" alt="image-20240425220308105" loading="lazy"></p>
<h3 id="6内嵌文档">6、内嵌文档</h3>
<blockquote>
<p>一个文档也可以作为另一个文档的<code>value</code></p>
</blockquote>
<pre><code class="language-bash">db.b1.insert({name:"三国演义",author:{name:"罗贯中",age:70}})
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104047173-1255973287.png" alt="image-20240425221008151" loading="lazy"></p>
<h2 id="七mongodb中的索引">七、MongoDB中的索引</h2>
<h3 id="1查看索引">1、查看索引</h3>
<blockquote>
<p>默认情况下,集合中的<code>_id</code>字段就是索引,我们可以通过<code>getIndexes()</code>方法来查看一个集合中的索引:</p>
</blockquote>
<pre><code class="language-bash">db.b1.getIndexes()
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104046853-249176909.png" alt="image-20240425222309926" loading="lazy"></p>
<ol>
<li><strong><code>v</code></strong>: 表示索引版本。在这个例子中,值为 <code>2</code>,表示这是一个版本 2 的索引。索引版本通常由 MongoDB 内部管理,用户通常不需要直接关心。</li>
<li><strong><code>key</code></strong>: 描述了索引的键(即排序依据)。键是一个对象,键名为字段名,键值为排序方向。在给出的例子中,<code>{ "_id" : 1 }</code> 表示索引基于字段 <code>_id</code>,且按升序(1)排序。在 MongoDB 中,每个集合都默认有一个名为 <code>_id</code> 的主键索引,它是唯一的,并且总是按升序排列。</li>
<li><strong><code>name</code></strong>: 指定索引的名称。这里为 <code>"name" : "_id_"</code>,表示这是一个针对 <code>_id</code> 字段的索引,其名称默认为 <code>_id_</code>。在 MongoDB 中,主键索引的名称通常是固定的,即 <code>_id_</code>。</li>
</ol>
<h3 id="2需要索引的查询场景">2、需要索引的查询场景</h3>
<h4 id="21创建有10000个文档的集合">2.1、创建有10000个文档的集合</h4>
<pre><code class="language-bash">for (var i=1;i<=10000;i++) {db.q1.insert({name:"test"+i , age: i})}
</code></pre>
<pre><code class="language-bash">db.q1.count()
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104046545-1374432207.png" alt="image-20240426082844602" loading="lazy"></p>
<h4 id="22查询age为200的文档">2.2、查询<code>age</code>为<code>200</code>的文档</h4>
<pre><code class="language-bash">db.q1.find({age:200})
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104046203-258495173.png" alt="image-20240425230647795" loading="lazy"></p>
<blockquote>
<p>这种查询默认情况下会做全表扫描,可以用<code>explain()</code>来查看一下查询计划</p>
</blockquote>
<pre><code class="language-bash">db.q1.find({age:200}).explain("executionStats")
</code></pre>
<pre><code class="language-bash">{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test3.q1",
"indexFilterSet" : false,
"parsedQuery" : {
"age" : {
"$eq" : 200
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"age" : {
"$eq" : 200
}
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 2,
"totalKeysExamined" : 0,
"totalDocsExamined" : 10000,
"executionStages" : {
"stage" : "COLLSCAN",
"filter" : {
"age" : {
"$eq" : 200
}
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 10002,
"advanced" : 1,
"needTime" : 10000,
"needYield" : 0,
"saveState" : 10,
"restoreState" : 10,
"isEOF" : 1,
"direction" : "forward",
"docsExamined" : 10000
}
},
"serverInfo" : {
"host" : "localhost.localdomain",
"port" : 27017,
"version" : "4.4.6",
"gitVersion" : "72e66213c2c3eab37d9358d5e78ad7f5c1d0d0d7"
},
"ok" : 1
}
</code></pre>
<p><strong>queryPlanner 部分</strong></p>
<ul>
<li><strong>plannerVersion</strong>: 表示查询优化器的版本。</li>
<li><strong>namespace</strong>: 查询涉及的集合名,即 <code>test3.q1</code>。</li>
<li><strong>indexFilterSet</strong>: 若为 <code>true</code>,表示查询使用了索引过滤器;此处为 <code>false</code>,说明没有使用。</li>
<li><strong>parsedQuery</strong>: 显示解析后的查询条件,即查找 <code>age</code> 字段等于 <code>200</code> 的文档。</li>
<li><strong>winningPlan</strong>: 描述被选择的执行计划。在这个案例中,执行计划的 <strong>stage</strong> 是 <code>"COLLSCAN"</code>,意味着进行了全集合扫描(Collection Scan)。这意味着为了找到匹配的文档,MongoDB 需要遍历整个 <code>q1</code> 集合,对每个文档应用 <strong>filter</strong> 中指定的条件(<code>age: { $eq: 200 }</code>)。</li>
<li><strong>rejectedPlans</strong>: 空数组,表示没有其他备选执行计划被否决。如果有多个可行计划,MongoDB 会选择成本最低的一个作为 winningPlan,其余的则记录在此处。</li>
</ul>
<p><strong>executionStats 部分</strong></p>
<p>这部分提供了实际执行查询时的统计信息:</p>
<ul>
<li><strong>executionSuccess</strong>: 指示查询是否成功完成,<code>true</code> 表示成功。</li>
<li><strong>nReturned</strong>: 返回的文档数量,这里是 <code>1</code>,说明找到了一个年龄为 <code>200</code> 的文档。</li>
<li><strong>executionTimeMillis</strong>: 执行查询所花费的时间(毫秒),本例中为 <code>2</code> 毫秒。</li>
<li><strong>totalKeysExamined</strong>: 查看的索引键数量。由于未使用索引,此处为 <code>0</code>。</li>
<li><strong>totalDocsExamined</strong>: 查看的文档数量,即全集合扫描过程中检查过的文档总数,这里为 <code>10000</code>,表明集合中有 10000 个文档被逐一检查以找出符合 <code>age: 200</code> 的文档。</li>
<li><strong>executionStages</strong>: 提供了更多关于执行阶段的细节,与 winningPlan 相对应。这里再次确认了进行了全集合扫描(<code>COLLSCAN</code>),并且实际查看了 10000 个文档 (<code>docsExamined</code>) 才找到 1 个匹配的文档 (<code>nReturned</code>).</li>
</ul>
<p><strong>serverInfo 部分</strong></p>
<ul>
<li>提供了运行 MongoDB 服务器的主机名、端口、版本号以及 Git 版本信息。</li>
</ul>
<p><strong>ok</strong></p>
<ul>
<li>值为 <code>1</code>,表示命令执行成功。</li>
</ul>
<h4 id="23添加limit查询文档">2.3、添加<code>limit</code>查询文档</h4>
<pre><code class="language-bash">db.q1.find({age:10}).limit(20)
db.q1.find({age:10}).limit(20).explain("executionStats")
</code></pre>
<pre><code class="language-bash">{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test3.q1",
"indexFilterSet" : false,
"parsedQuery" : {
"age" : {
"$eq" : 10
}
},
"winningPlan" : {
"stage" : "LIMIT",
"limitAmount" : 20,
"inputStage" : {
"stage" : "COLLSCAN",
"filter" : {
"age" : {
"$eq" : 10
}
},
"direction" : "forward"
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 4,
"totalKeysExamined" : 0,
"totalDocsExamined" : 10000,
"executionStages" : {
"stage" : "LIMIT",
"nReturned" : 1,
"executionTimeMillisEstimate" : 1,
"works" : 10002,
"advanced" : 1,
"needTime" : 10000,
"needYield" : 0,
"saveState" : 10,
"restoreState" : 10,
"isEOF" : 1,
"limitAmount" : 20,
"inputStage" : {
"stage" : "COLLSCAN",
"filter" : {
"age" : {
"$eq" : 10
}
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 1,
"works" : 10002,
"advanced" : 1,
"needTime" : 10000,
"needYield" : 0,
"saveState" : 10,
"restoreState" : 10,
"isEOF" : 1,
"direction" : "forward",
"docsExamined" : 10000
}
}
},
"serverInfo" : {
"host" : "localhost.localdomain",
"port" : 27017,
"version" : "4.4.6",
"gitVersion" : "72e66213c2c3eab37d9358d5e78ad7f5c1d0d0d7"
},
"ok" : 1
}
</code></pre>
<blockquote>
<p>可以明显感受到加了<code>limit</code>后查询速度变快了很多</p>
<p>但是如果我们查询<code>age</code>为<code>9999</code>的文档那么还是得全表扫描一遍</p>
<p>此时我们就可以给该字段加上索引</p>
</blockquote>
<h4 id="24创建索引">2.4、创建索引</h4>
<pre><code class="language-bash">db.collection.createIndex(keys, options)
</code></pre>
<p><strong>参数:</strong></p>
<ul>
<li>
<p>keys:</p>
<ul>
<li>包含字段和值对的文档,其中字段是索引键,描述该字段的索引类型</li>
<li>对于字段的上升索引,请指定为1,对于降序指定为-1</li>
</ul>
</li>
<li>
<p>options:</p>
<ul>
<li>可选,包含一组控制索引创建的选项的文档</li>
</ul>
<table>
<thead>
<tr>
<th style="text-align: center">选项</th>
<th style="text-align: center">类型</th>
<th style="text-align: center">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">background</td>
<td style="text-align: center">布尔</td>
<td style="text-align: center">是否在后台执行创建索引的过程,不阻塞对集合的操作false【默认】</td>
</tr>
<tr>
<td style="text-align: center">unique</td>
<td style="text-align: center">布尔</td>
<td style="text-align: center">是否创建具有唯一性的索引 false【默认】</td>
</tr>
<tr>
<td style="text-align: center">name</td>
<td style="text-align: center">字符串</td>
<td style="text-align: center">自定义索引名称,如果不指定,mongodb将通过 下划线 连接 索引字段的名称和排序规则 生成一个索引名称。一旦创建不能修改,只能删除再重新创建</td>
</tr>
<tr>
<td style="text-align: center">partialFilterExpression</td>
<td style="text-align: center">Document</td>
<td style="text-align: center">仅为集合中符合条件的文档建立索引,降低创建和维护成本</td>
</tr>
<tr>
<td style="text-align: center">sparse</td>
<td style="text-align: center">布尔</td>
<td style="text-align: center">仅为集合中具有指定字段的文档建立索引 false 【默认】</td>
</tr>
<tr>
<td style="text-align: center">expireAfterSeconds</td>
<td style="text-align: center">integer单位 秒</td>
<td style="text-align: center">用于 TTL 索引中 控制 文档保存在集合中的时间</td>
</tr>
<tr>
<td style="text-align: center">storageEngine</td>
<td style="text-align: center">Document</td>
<td style="text-align: center">指定存储引擎配置</td>
</tr>
</tbody>
</table>
</li>
</ul>
<pre><code class="language-bash">db.q1.ensureIndex({age:1})
</code></pre>
<blockquote>
<p>查看查询计划</p>
</blockquote>
<pre><code>db.q1.find({age:200}).explain("executionStats")
</code></pre>
<pre><code class="language-bash">> db.q1.find({age:200}).explain("executionStats")
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test3.q1",
"indexFilterSet" : false,
"parsedQuery" : {
"age" : {
"$eq" : 200
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"age" : 1
},
"indexName" : "age_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"age" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"age" : [
""
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 1,
"totalKeysExamined" : 1,
"totalDocsExamined" : 1,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 2,
"advanced" : 1,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"docsExamined" : 1,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 2,
"advanced" : 1,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"keyPattern" : {
"age" : 1
},
"indexName" : "age_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"age" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"age" : [
""
]
},
"keysExamined" : 1,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0
}
}
},
"serverInfo" : {
"host" : "localhost.localdomain",
"port" : 27017,
"version" : "4.4.6",
"gitVersion" : "72e66213c2c3eab37d9358d5e78ad7f5c1d0d0d7"
},
"ok" : 1
}
</code></pre>
<blockquote>
<ul>
<li>
<p><strong>executionTimeMillis</strong>:执行耗时 1 毫秒。</p>
</li>
<li>
<p><strong>totalKeysExamined</strong> 和 <strong>totalDocsExamined</strong>:分别检查了 1 个索引键和 1 个文档。由于使用了覆盖索引(即索引包含了查询所需的所有字段),这里的两个值相等,意味着无需额外查询文档。</p>
</li>
</ul>
</blockquote>
<blockquote>
<p>查看索引</p>
</blockquote>
<pre><code class="language-bash">> db.q1.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
},
{
"v" : 2,
"key" : {
"age" : 1
},
"name" : "age_1"
}
]
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104045828-383784010.png" alt="image-20240426093010417" loading="lazy"></p>
<h4 id="25自定义索引名字">2.5、自定义索引名字</h4>
<pre><code class="language-bash">db.q1.ensureIndex({name:1},{name:"MyNameIndex"})
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104045453-505864974.png" alt="image-20240426102603193" loading="lazy"></p>
<h3 id="3查看索引的大小">3、查看索引的大小</h3>
<blockquote>
<p>默认单位是字节</p>
</blockquote>
<pre><code class="language-bash">db.q1.totalIndexSize()
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104045136-1260565276.png" alt="image-20240426102044812" loading="lazy"></p>
<h3 id="4删除索引">4、删除索引</h3>
<h4 id="41按名称删除索引">4.1、按名称删除索引</h4>
<pre><code class="language-bash">db.q1.dropIndex("MyNameIndex")
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104044804-653231475.png" alt="image-20240426102841487" loading="lazy"></p>
<h4 id="42删除所有的索引">4.2、删除所有的索引</h4>
<pre><code class="language-bash">db.q1.dropIndexes()
</code></pre>
<p><img src="https://img2023.cnblogs.com/blog/3332572/202404/3332572-20240426104044094-1259613579.png" alt="image-20240426103015481" loading="lazy"></p>
<h3 id="5优缺点">5、优缺点</h3>
<h4 id="51优点">5.1、优点:</h4>
<ul>
<li><strong>提高查询性能:</strong>索引能够大大加快数据查询速度,特别是对于含有复杂查询条件、排序、分组或聚合操作的查询。</li>
<li><strong>支持高效排序</strong>:当查询需要对特定字段进行排序时,如果该字段有索引,MongoDB可以直接利用索引来完成排序,避免了大量数据的内部排序操作,显著提升性能。</li>
<li><strong>覆盖查询</strong>:如果一个索引包含了查询所需的全部字段,称为“覆盖索引”。在这种情况下,MongoDB可以直接从索引中获取所有数据,而无需访问实际文档,从而减少磁盘I/O操作,提高查询效率。</li>
<li><strong>唯一性约束</strong>:创建唯一索引可以确保指定字段的值在整个集合中唯一,防止插入重复数据,确保数据完整性。</li>
</ul>
<h4 id="52缺点">5.2、缺点:</h4>
<ul>
<li><strong>占用存储空间</strong>:索引需要额外的存储空间来保存索引数据结构。随着数据量的增长和索引数量的增加,存储开销会逐渐增大。需要根据实际业务需求权衡查询性能与存储成本。</li>
<li><strong>写操作性能影响</strong>:插入、更新和删除文档时,不仅要修改原数据,还要同步更新相关索引。对于写密集型应用,大量的索引可能导致写操作性能下降,尤其是当索引较多或索引字段频繁变动时。</li>
<li><strong>索引维护成本</strong>:随着数据的变化,索引需要不断维护和更新。对于大型数据集,索引重建可能需要消耗较长时间和系统资源。此外,随着业务发展,可能需要定期评估和调整索引策略,以适应新的查询模式。</li>
</ul><br><br>
来源:https://www.cnblogs.com/misakivv/p/18159503
頁:
[1]