方圆系统 發表於 2019-8-5 19:41:00

MongoDB

<h1 id="mongodb">MongoDB</h1>
<p><em><strong>本文非常长,共计12200词,请注意阅读时间,撰写四天时间,原创不易,转载请注明。</strong></em></p>
<h2 id="一概述">一、概述</h2>
<h3 id="1数据">1.数据</h3>
<p>能够输入到计算机中并被识别处理的信息集合</p>
<h3 id="2-数据结构">2. 数据结构</h3>
<p>研究一个数据集合中,数据元素关系</p>
<h3 id="3-数据库">3. 数据库</h3>
<p>按照数据结构,存储管理数据的仓库,数据仓库是在数据库管理系统控制下在一定介质中创建的</p>
<h3 id="4数据库管理系统">4.数据库管理系统</h3>
<p>数据库管理软件</p>
<h3 id="5数据库系统">5.数据库系统</h3>
<p>由数据库和数据库管理系统等构成的数据开发工具集合</p>
<h2 id="二-关系与非关系">二、 关系与非关系</h2>
<h3 id="1-关系型数据库">1. 关系型数据库</h3>
<p>采用关系模型(二维表)来组织数据结构的数据库</p>
<blockquote>
<p>Oracle、DB2、SQLServer、MySQL、SQLite</p>
</blockquote>
<p>优点</p>
<ul>
<li>逻辑清晰,容易理解,结构类似于常见的表格</li>
<li>使用SQL语句,技术成熟,使用方便</li>
<li>关系型数据库比较成熟,可以使用一些复杂的操作</li>
</ul>
<p>缺点</p>
<ul>
<li>每次操作都需要专门的SQL解析</li>
<li>关系型数据库结构严格,内部加锁</li>
<li>在应对海量数据并发处理时读写速度差</li>
</ul>
<h3 id="2-非关系型数据库">2. 非关系型数据库</h3>
<p>没有采用关系模型(二维表)来组织数据结构的数据库</p>
<blockquote>
<p>键值型:Redis</p>
<p>列存储:HBase</p>
<p>文档型:MongoDB</p>
<p>图形:Graph</p>
</blockquote>
<p>优点</p>
<ul>
<li>读写速度快,能更好的针对并发处理</li>
<li>使用灵活,容易扩展</li>
</ul>
<p>缺点</p>
<ul>
<li>没有sql那样统一成熟的语句</li>
<li>技术程度较差,缺少一些复杂的操作</li>
</ul>
<p>应用场景</p>
<ul>
<li>对数据结构要求不严格,比较灵活</li>
<li>对数据处理的速度,特别是海量数据的并发处理速度要求比较高</li>
<li>特定场景:需要灵活扩展,需要作为缓存</li>
</ul>
<h2 id="三mongodb">三、MongoDB</h2>
<h3 id="1-特点">1. 特点</h3>
<ul>
<li>非关系型数据库,是属于文档型数据库</li>
<li>开源数据库,使用广泛</li>
<li>由c++编写的数据库管理系统</li>
<li>支持丰富的存储类型和数据操作</li>
<li>提供了丰富的编程语言接口</li>
<li>方便扩展和部署</li>
</ul>
<h3 id="2-安装">2. 安装</h3>
<p>Ubuntu:<code>sudo apt-get install mongodb</code></p>
<p>Mac:<code>brew install mongodb</code></p>
<p>Windows:<code>www.mongodb.com</code></p>
<blockquote>
<p>ubuntu安装位置:<code>/var/lib/mongodb</code></p>
<p>配置文件:<code>/etc/mongodb.conf</code></p>
<p>命令集:<code>/usr/bin/</code></p>
</blockquote>
<h3 id="3-基础命令">3. 基础命令</h3>
<p>名称:<code>mongodb shell</code></p>
<p>命令:<code>mongo</code></p>
<p>退出:<code>quit()</code></p>
<p>mongod 设置MongoDB的基本信息</p>
<blockquote>
<p><code>mongod -h</code> //查看帮助</p>
<p><code>mongod --dbpath </code> //设置数据库存储位置</p>
<p><code>mongod --port </code> //设置数据库端口</p>
<p>*默认端口为27017</p>
</blockquote>
<h2 id="四数据结构">四、数据结构</h2>
<p>数据组织结构:键值对--&gt;文档--&gt;集合--&gt;数据库</p>
<p>例如:</p>
<p>MySQL</p>
<p><img src="https://img2018.cnblogs.com/blog/1458652/201908/1458652-20190805193507170-307342446.png" alt="" loading="lazy"></p>
<p>MongoDB</p>
<p><img src="https://img2018.cnblogs.com/blog/1458652/201908/1458652-20190805193522161-1385403422.png" alt="" loading="lazy"></p>
<table>
<thead>
<tr>
<th style="text-align: left">MySQL</th>
<th>MongoDB</th>
<th>含义</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left">databases</td>
<td>databases</td>
<td>数据库</td>
</tr>
<tr>
<td style="text-align: left">table</td>
<td>collection</td>
<td>表/集合</td>
</tr>
<tr>
<td style="text-align: left">column</td>
<td>field</td>
<td>字段/域</td>
</tr>
<tr>
<td style="text-align: left">row</td>
<td>document</td>
<td>记录/文档</td>
</tr>
<tr>
<td style="text-align: left">index</td>
<td>index</td>
<td>索引</td>
</tr>
</tbody>
</table>
<h2 id="五数据库操作">五、数据库操作</h2>
<h3 id="1-数据库操作">1. 数据库操作</h3>
<p><code>use </code>创建数据库</p>
<blockquote>
<p>use实际是选择使用哪个数据库,当这个数据库不存在的时候,自动创建</p>
<p>但是不会立即建立,只有插入数据的时候才会真正建立</p>
</blockquote>
<p><code>show dbs</code>查看数据库</p>
<p><code>db.class.insert({"name":"Lily","age":"17"})</code> 插入简单的数据</p>
<p><code>db.dropDatabase()</code> 删除当前数据库,在use之后执行,就会删除当前数据库</p>
<blockquote>
<p>数据库命名规则</p>
<ul>
<li>
<p>使用UTF-8字符串</p>
</li>
<li>
<p>不能含有<code>空格``.``/``\``\0</code>字符</p>
</li>
<li>
<p>不能超过64字节长度</p>
</li>
<li>
<p>不要和系统库重名</p>
</li>
</ul>
<p>db代表当前正在使用的数据库,进入数据库默认使用`tes</p>
</blockquote>
<h3 id="2-备份恢复">2. 备份恢复</h3>
<blockquote>
<p>数据库的备份恢复</p>
<p><code>mongodump -h -d -o {path]</code>备份</p>
<p><code>mongorestore -h -d </code> 恢复</p>
</blockquote>
<h3 id="3-运行监控">3. 运行监控</h3>
<h4 id="31-运行状态">3.1 运行状态</h4>
<p><code> mongostat</code> 查看数据库运行状态(只要修改磁盘的都是写操作,查是读操作)</p>
<p><img src="https://img2018.cnblogs.com/blog/1458652/201908/1458652-20190805193554931-1411082143.png" alt="" loading="lazy"></p>
<p><code>insert</code> <code>query</code> <code>update</code> <code>delete</code> 每秒增查改删的次数</p>
<p><code>getmore</code></p>
<p><code>command</code> 每秒执行MongoDB命令的次数</p>
<p><code>dirty</code></p>
<p><code>used </code></p>
<p><code>flushes </code>每秒刷新磁盘的次数</p>
<p><code>vsize</code>虚拟内存使用情况</p>
<p><code>res </code>物理内存使用情况</p>
<p><code>qrw </code></p>
<p><code>arw </code></p>
<p><code>net_in</code></p>
<p><code>net_out </code></p>
<p><code>conn   </code></p>
<p><code>time</code>当前时间</p>
<h4 id="32-读写时长">3.2 读写时长</h4>
<p><code>mongotop</code> 查看数据库读写时长</p>
<blockquote>
<p>2019-08-01T11:14:53.678+0800    connected to: 127.0.0.1</p>
<pre><code>                ns    total    read    write    2019-08-01T11:14:54+08:00
admin.system.roles      0ms   0ms      0ms
</code></pre>
<p>admin.system.version      0ms   0ms      0ms<br>
config.system.sessions      0ms   0ms      0ms<br>
local.startup_log      0ms   0ms      0ms<br>
local.system.replset      0ms   0ms      0ms<br>
stu.class      0ms   0ms      0ms<br>
student.class      0ms   0ms      0ms</p>
</blockquote>
<p>得到每个集合在每秒之内的读写时间</p>
<h2 id="六集合操作">六、集合操作</h2>
<p><code>db.createCollection(collectionName)</code> 创建集合</p>
<p><code>show collections</code>或者<code>show tables</code> 查看集合</p>
<p><code>db.collection.insert(...)</code> 插入数据(如果该集合不存在,则自动创建)</p>
<p><code>db.collection.drop()</code> 删除集合</p>
<p><code>db.collection.renameCollection(NewName)</code> 集合重命名</p>
<blockquote>
<p>集合命名规则</p>
<ul>
<li>使用UTF-8字符</li>
<li>不能含有<code>'\0'</code></li>
<li>不要以<code>system.</code>开头,这是系统集合默认开头</li>
<li>不要和关键字重名</li>
</ul>
</blockquote>
<h2 id="七文档操作">七、文档操作</h2>
<h3 id="1-概述">1. 概述</h3>
<p>文档是MongoDB中基本的数据组织单元</p>
<p>文档由键值对构成,每个键值对表达一个数据项</p>
<p>MongoDB的文档属于<code>bson</code>类型数据</p>
<blockquote>
<p>bson--&gt;Json--&gt;JavaScript</p>
</blockquote>
<p>文档键值对特点</p>
<ul>
<li>无序的</li>
<li>通过键值对取值</li>
<li>不能重复</li>
<li>键是UTF-8字符串,不能有<code>\0</code>字符</li>
</ul>
<h3 id="2-数据类型">2. 数据类型</h3>
<h4 id="21-整型">2.1 整型</h4>
<p><code>int </code>: 整数</p>
<h4 id="22-浮点型">2.2 浮点型</h4>
<p><code>double</code> : 小数</p>
<h4 id="23-布尔">2.3 布尔</h4>
<p><code>boolean</code> : true/false</p>
<h4 id="24-字符串">2.4 字符串</h4>
<p><code>string</code> :utf-8字符串</p>
<h4 id="25-objectid">2.5 ObjectID</h4>
<p>id对象</p>
<pre><code>&gt; db.class0.find()
{ "_id" : ObjectId("5d42519a1ae0b26ac7985b89"), "name" : "Lily", "age" : 17 }
</code></pre>
<blockquote>
<p>其实质就是一串16进制,通过一定的算法,生成不重复的24位的16进制值</p>
<p>MongoDB插入文档时,每个文档都要有一个_id与,可以自己指定一个不重复的值,也可以由系统自动生成</p>
</blockquote>
<h3 id="3集合文档设计">3.集合文档设计</h3>
<ul>
<li>一个集合中的文档可以有不同的域,域的个数也可以不一致</li>
<li>集合中的文档层次不宜嵌套过多,如果层次过多时应考虑分为多个集合</li>
<li>在一个集合中的文档应该尽量表达相同类型的数据类型</li>
</ul>
<h2 id="八数据操作">八、数据操作</h2>
<h3 id="1-插入文档">1. 插入文档</h3>
<p><code>db.collection.insertOne(doc)</code></p>
<p>功能:插入一条文档</p>
<p>参数:一条要插入的文档</p>
<pre><code>&gt; db.class0.insertOne({"name":"Lucy","age":18,"sex":"女"})
{
      "acknowledged" : true,
      "insertedId" : ObjectId("5d428df01bc9a3414430192e")
}
</code></pre>
<blockquote>
<p>操作时,键可以不加引号</p>
<p>可以自己设置<code>_id</code>值,但是不能重复</p>
</blockquote>
<p><code>db.collection.insertMany([{...},{...},{...}])</code></p>
<p>功能:插入多条文档</p>
<p>参数:数组中为多个文档</p>
<pre><code>&gt; db.class.insertMany([{name:'波多野结衣',age:33,sex:"女"},{name:"苍井空",age:36,sex:"
女"},{name:"麻生希",age:30,sex:"女" }])
{
      "acknowledged" : true,
      "insertedIds" : [
                ObjectId("5d42915d1bc9a34144301930"),
                ObjectId("5d42915d1bc9a34144301931"),
                ObjectId("5d42915d1bc9a34144301932")
      ]
}
&gt; db.class.find()
{ "_id" : ObjectId("5d42915d1bc9a34144301930"), "name" : "波多野结衣", "age" : 33, "sex
" : "女" }
{ "_id" : ObjectId("5d42915d1bc9a34144301931"), "name" : "苍井空", "age" : 36, "sex" :
"女" }
{ "_id" : ObjectId("5d42915d1bc9a34144301932"), "name" : "麻生希", "age" : 30, "sex" :
"女" }
</code></pre>
<blockquote>
<p>数组:使用<code>[ ]</code>表示 的一组数据有序集合</p>
<p>特点:有序,使用序列号取值</p>
</blockquote>
<p>练习</p>
<blockquote>
<p>创建grade数据库</p>
<p>创建class集合</p>
<p>集合中插入若干数据项,格式如下</p>
<p><code>{name:xxx,age:xxx,sex:x,hobby:}</code></p>
<p>规则:年龄(7-15)、hobby(draw、dance、sing、football、basketball、computer、python)</p>
</blockquote>
<pre><code>use grade
db.class.insertOne(
        {name:"Chancey",age:18,sex:"男",hobby:["draw","dance","sing"]}
        )
db.class.insertMany([
        {name:"小红",age:18,sex:"女",hobby:["draw","python"]},       
        {name:"小明",age:23,sex:"男",hobby:["sing","football"]},
        {name:"小花",age:35,sex:"女",hobby:["python","computer"]},       
        {name:"小绿",age:22,sex:"女",hobby:["computer","draw"]},       
        ])
</code></pre>
<p><code>db.collection.insert()</code></p>
<p>功能:插入多条数据</p>
<p>参数:同insertOne + insertMany(可以是文档,也可以是数组里面嵌套文档)</p>
<blockquote>
<p>官方已经不太推荐,所以使用上述两种方法插入数据更为稳定</p>
</blockquote>
<p><code>db.collection.save()</code></p>
<p>功能:插入一条或者多条文档</p>
<p>参数:同insert</p>
<pre><code>db.class0.save({name:'Alex',age:18,sex:"男"})

db.class0.save([
        {name:"小花",age:35,sex:"女",hobby:["python","computer"]},       
        {name:"小绿",age:22,sex:"女",hobby:["computer","draw"]}
        ])
</code></pre>
<blockquote>
<p>当_id冲突的时候,save则会覆盖掉已经存在的记录</p>
</blockquote>
<h3 id="2-查询文档">2. 查询文档</h3>
<h4 id="21-find">2.1 find</h4>
<p><img src="https://img2018.cnblogs.com/blog/1458652/201908/1458652-20190805193720871-1128844238.png" alt="" loading="lazy"></p>
<p><code>db.clooect.find(query,field)</code></p>
<p>功能:查找所有的符合条件的文档</p>
<p>参数:query(要查找的文档)、field(要查找的域)</p>
<p>返回值:返回所有查找到的文档</p>
<p><strong>参数使用方法</strong></p>
<h5 id="211-query">2.1.1 query</h5>
<p>是一个键值对文档<code>{}</code>,空则表示查找所有</p>
<p>以键值对表示筛选条件,往往配合查找操作符完成</p>
<h5 id="212-field">2.1.2 field</h5>
<p>是一个键值对文档<code>{}</code>,<code>field:0</code>表示不查找这个域,<code>field:1</code>表示查找这个域</p>
<pre><code>&gt; db.class0.find({age:18},{name:1,age:1})
{ "_id" : ObjectId("5d428df01bc9a3414430192e"), "name" : "Lucy", "age" : 18 }
{ "_id" : ObjectId("5d42a1621bc9a3414430193b"), "name" : "Alex", "age" : 18 }
&gt; db.class0.find({age:18},{_id:0})
{ "name" : "Lucy", "age" : 18, "sex" : "女" }
{ "name" : "Alex", "age" : 18, "sex" : "男" }
&gt; db.class0.find({age:18},{_id:0,sex:0})
{ "name" : "Lucy", "age" : 18 }
{ "name" : "Alex", "age" : 18 }
&gt; db.class0.find({age:18},{_id:0,age:1,sex:1})
{ "age" : 18, "sex" : "女" }
{ "age" : 18, "sex" : "男" }
</code></pre>
<blockquote>
<p><code>_id</code>域如果不想查找,则<code>_d:0</code></p>
<p>其他域要么全为0,要么全为1</p>
</blockquote>
<h4 id="22-findone">2.2 findOne</h4>
<p><code>db.collection.findOne(query,field)</code></p>
<p>功能:查找第一个符合条件的文档</p>
<p>参数:同find</p>
<p>返回值:返回查找到的文档</p>
<pre><code>&gt; db.class.findOne()
{
      "_id" : ObjectId("5d42915d1bc9a34144301930"),
      "name" : "波多",
      "age" : 33,
      "sex" : "女"
}
&gt; db.class0.findOne({age:18})
{
      "_id" : ObjectId("5d428df01bc9a3414430192e"),
      "name" : "Lucy",
      "age" : 18,
      "sex" : "女"
}
&gt; db.class0.findOne({age:20},{_id:0})
{ "name" : "素心", "age" : 20, "sex" : "男" }
</code></pre>
<blockquote>
<p>如果没有参数则默认查找所有记录的第一条</p>
</blockquote>
<h4 id="23-query操作符">2.3 query操作符</h4>
<p>操作符:MongoDB中使用<code>$</code>注明的一个有特殊意义的字符串,用以表达丰富的含义,比如:<code>$lt</code>表示小于</p>
<h5 id="231-比较操作符">2.3.1 比较操作符</h5>
<table>
<thead>
<tr>
<th>序号</th>
<th>字符</th>
<th>汉义</th>
<th>符号</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>$eq</td>
<td>等于</td>
<td>=</td>
</tr>
<tr>
<td>2</td>
<td>$lt</td>
<td>小于</td>
<td>&lt;</td>
</tr>
<tr>
<td>3</td>
<td>$gt</td>
<td>大于</td>
<td>&gt;</td>
</tr>
<tr>
<td>4</td>
<td>$lte</td>
<td>小于等于</td>
<td>&lt;=</td>
</tr>
<tr>
<td>5</td>
<td>$gte</td>
<td>大于等于</td>
<td>&gt;=</td>
</tr>
<tr>
<td>6</td>
<td>$ne</td>
<td>不等于</td>
<td>!=</td>
</tr>
<tr>
<td>7</td>
<td>$in</td>
<td>包含</td>
<td></td>
</tr>
<tr>
<td>8</td>
<td>$nin</td>
<td>不包含</td>
<td></td>
</tr>
</tbody>
</table>
<pre><code>#查找年龄为20的
&gt; db.class0.find({age:{$eq:20}},{_id:0})
{ "name" : "素心", "age" : 20, "sex" : "男" }
&gt; db.class0.find({sex:{$eq:"女"}},{_id:0})
{ "name" : "Lucy", "age" : 18, "sex" : "女" }
{ "name" : "Chancey", "age" : 17, "sex" : "女" }

#查找年龄小于16的
&gt; db.class0.find({age:{$lt:16}},{_id:0})
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }

#查找年龄大于17切小于20的(区间查找)
&gt; db.class0.find({age:{$gt:17,$lt:20}},{_id:0})
{ "name" : "Lucy", "age" : 18, "sex" : "女" }
{ "name" : "Alex", "age" : 18, "sex" : "男" }

#查找年龄小于等于13的
&gt; db.class0.find({age:{$lte:13}},{_id:0})
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }

#查找年龄大于等于20的
&gt; db.class0.find({age:{$gte:20}},{_id:0})
{ "name" : "素心", "age" : 20, "sex" : "男" }
{ "name" : "Abby", "age" : 21, "sex" : "男" }

#查找年龄不等于13的
&gt; db.class0.find({age:{$ne:13}},{_id:0})
{ "name" : "Lily", "age" : 17 }
{ "name" : "Lucy", "age" : 18, "sex" : "女" }
{ "name" : "Chancey", "age" : 17, "sex" : "女" }
{ "name" : "素心", "age" : 20, "sex" : "男" }
{ "name" : "Abby", "age" : 21, "sex" : "男" }
{ "name" : "Alex", "age" : 18, "sex" : "男" }
{ "name" : "Alex", "age" : 17, "sex" : "男" }

# 查找年龄等于13、16、20的
&gt; db.class0.find({age:{$in:}},{_id:0})
{ "name" : "素心", "age" : 20, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }

#查找年龄不等于13、16、20的
&gt; db.class0.find({age:{$nin:}},{_id:0})
{ "name" : "Lily", "age" : 17 }
{ "name" : "Lucy", "age" : 18, "sex" : "女" }
{ "name" : "Chancey", "age" : 17, "sex" : "女" }
{ "name" : "Abby", "age" : 21, "sex" : "男" }
{ "name" : "Alex", "age" : 18, "sex" : "男" }
{ "name" : "Alex", "age" : 17, "sex" : "男" }
</code></pre>
<blockquote>
<p>包含的关系的写法</p>
<p>在<code>$ne</code>的值里面填写数组,表示以该数组为集合查找任意符合条件的记录</p>
</blockquote>
<h5 id="232--逻辑操作符">2.3.2逻辑操作符</h5>
<table>
<thead>
<tr>
<th>序号</th>
<th>字符</th>
<th>汉义</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>$and</td>
<td>与</td>
</tr>
<tr>
<td>2</td>
<td>$or</td>
<td>或</td>
</tr>
<tr>
<td>3</td>
<td>$not</td>
<td>非</td>
</tr>
<tr>
<td>4</td>
<td>$nor</td>
<td>既不也不</td>
</tr>
</tbody>
</table>
<pre><code># 查找年龄大于17且为男的
&gt; db.class0.find({$and:[{age:{$gt:17}},{sex:"男"}]},{_id:0})
{ "name" : "素心", "age" : 20, "sex" : "男" }
{ "name" : "Abby", "age" : 21, "sex" : "男" }
{ "name" : "Alex", "age" : 18, "sex" : "男" }
# 查找姓名小于Lily且年龄为17,19,21的
&gt; db.class0.find({$and:[{name:{$lt:"Lily"}},{age:{$in:}}]},{_id:0})
{ "name" : "Chancey", "age" : 17, "sex" : "女" }
{ "name" : "Abby", "age" : 21, "sex" : "男" }
{ "name" : "Alex", "age" : 17, "sex" : "男" }

#查找年龄大于18或性别为女
&gt; db.class0.find({$or:[{age:{$gt:18}},{sex:{$eq:"女"}}]},{_id:0})
{ "name" : "Lucy", "age" : 18, "sex" : "女" }
{ "name" : "Chancey", "age" : 17, "sex" : "女" }
{ "name" : "素心", "age" : 20, "sex" : "男" }
{ "name" : "Abby", "age" : 21, "sex" : "男" }
#查找年龄小于18或大于19
&gt; db.class0.find({$or:[{age:{$lt:18}},{age:{$gt:19}}]},{_id:0})
{ "name" : "Lily", "age" : 17 }
{ "name" : "Chancey", "age" : 17, "sex" : "女" }
{ "name" : "素心", "age" : 20, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Abby", "age" : 21, "sex" : "男" }
{ "name" : "Alex", "age" : 17, "sex" : "男" }

#查找年龄不大于18的
&gt; db.class0.find({age:{$not:{$gt:18}}},{_id:0})
{ "name" : "Lily", "age" : 17 }
{ "name" : "Lucy", "age" : 18, "sex" : "女" }
{ "name" : "Chancey", "age" : 17, "sex" : "女" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Alex", "age" : 18, "sex" : "男" }
{ "name" : "Alex", "age" : 17, "sex" : "男" }

#查找年龄不大于18性别也不为男
&gt; db.class0.find({$nor:[{age:{$gt:18}},{sex:{$eq:"男"}}]},{_id:0})
{ "name" : "Lily", "age" : 17 }
{ "name" : "Lucy", "age" : 18, "sex" : "女" }
{ "name" : "Chancey", "age" : 17, "sex" : "女" }
</code></pre>
<blockquote>
<p>使用逻辑操作符的时候,在特殊符号的值应为数组,数组里面包含条件</p>
<p>$not的格式与三目运算不一样,注意</p>
</blockquote>
<h5 id="233-混合查询">2.3.3 混合查询</h5>
<pre><code>#年龄大于等于17的男生,或者名字叫Addy或者Emmm
&gt; db.class0.find({$or:[{$and:[{age:{$gt:17}},{sex:{$eq:"男"}}]},{$or:[{name:"Addy"},{na me:"Emmm"}]}]},{_id:0})
{ "name" : "素心", "age" : 20, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Abby", "age" : 21, "sex" : "男" }
{ "name" : "Alex", "age" : 18, "sex" : "男" }
</code></pre>
<h5 id="234-数组操作符">2.3.4 数组操作符</h5>
<h6 id="查找数组中包含元素">查找数组中包含元素</h6>
<pre><code># 查找score数组大于90的记录
&gt; db.class2.find({score:{$gt:90}},{_id:0})
{ "name" : "小红", "age" : 9, "score" : [ 97, 89, 87 ] }
</code></pre>
<blockquote>
<p>当键对应的值为一个数组的时候,query填入一个包含关系的元素即可查找</p>
</blockquote>
<h6 id="查找数组中同时包含多项">查找数组中同时包含多项</h6>
<p><code>$all</code></p>
<pre><code># 查找既包含87,又包含89的
&gt; db.class2.find({score:{$all:}},{_id:0})
{ "name" : "小红", "age" : 9, "score" : [ 97, 89, 87 ] }
</code></pre>
<h6 id="根据数组的元素个数查找">根据数组的元素个数查找</h6>
<p><code>$size</code></p>
<pre><code>查找数组元素个数为3的记录
&gt; db.class2.find({score:{$size:3}},{_id:0})
{ "name" : "小明", "age" : 10, "score" : [ 87, 69, 81 ] }
{ "name" : "小红", "age" : 9, "score" : [ 97, 89, 87 ] }
{ "name" : "小刚", "age" : 9, "score" : [ 90, 79, 90 ] }
</code></pre>
<h6 id="切片操作">切片操作</h6>
<p>用于field参数,表示查找数组哪些项</p>
<p><code>$slice</code></p>
<pre><code># 查找指定数组的前两项
&gt; db.class2.find({},{_id:0,score:{$slice:2}})
{ "name" : "小明", "age" : 10, "score" : [ 87, 69 ] }
{ "name" : "小红", "age" : 9, "score" : [ 97, 89 ] }
{ "name" : "小刚", "age" : 9, "score" : [ 90, 79 ] }
# 跳过前一项,查看之后的两项
&gt; db.class2.find({},{_id:0,score:{$slice:}})
{ "name" : "小明", "age" : 10, "score" : [ 69, 81 ] }
{ "name" : "小红", "age" : 9, "score" : [ 89, 87 ] }
{ "name" : "小刚", "age" : 9, "score" : [ 79, 90 ] }
</code></pre>
<blockquote>
<p>可以指定哪些数组显示哪些元素</p>
<p>表示跳过m项,查询m项之后的n项元素</p>
<blockquote>
<p>如果超过数组元素个数,则显示最多的元素</p>
</blockquote>
</blockquote>
<h6 id="通过索引查找">通过索引查找</h6>
<p>query中<code>域名.序列号</code>表示查找该数组某元素指定值的范围</p>
<pre><code># 查找socre下第1项大于80的记录
&gt; db.class2.find({"score.1":{$gt:80}},{_id:0})
{ "name" : "小红", "age" : 9, "score" : [ 97, 89, 87 ] }
</code></pre>
<blockquote>
<p>数组序列号也是从0开始数</p>
</blockquote>
<h5 id="235-其他操作符">2.3.5 其他操作符</h5>
<p>$exists 判断一个域是否存在</p>
<pre><code># 查找age域的所有文档
&gt; db.class2.find({age:{$exists:true}},{_id:0})
{ "name" : "小明", "age" : 10, "score" : [ 87, 69, 81 ] }
{ "name" : "小红", "age" : 9, "score" : [ 97, 89, 87 ] }
{ "name" : "小刚", "age" : 9, "score" : [ 90, 79, 90 ] }
</code></pre>
<p>$mod 根据除数余数筛选</p>
<pre><code># 查找年龄为奇数的文档
&gt; db.class0.find({age:{$mod:}},{_id:0})
{ "name" : "Lily", "age" : 17 }
{ "name" : "Chancey", "age" : 17, "sex" : "女" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Abby", "age" : 21, "sex" : "男" }
{ "name" : "Alex", "age" : 17, "sex" : "男" }
</code></pre>
<blockquote>
<p><code>mod:</code>表示该数除以m,余n的文档</p>
</blockquote>
<p>$type 根据类型筛选</p>
<pre><code>&gt; db.class0.find({age:{$type:2}},{_id:0})
&gt; db.class0.find({age:{$type:1}},{_id:0})
{ "name" : "Lily", "age" : 17 }
{ "name" : "Lucy", "age" : 18, "sex" : "女" }
{ "name" : "Chancey", "age" : 17, "sex" : "女" }
{ "name" : "素心", "age" : 20, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Abby", "age" : 21, "sex" : "男" }
{ "name" : "Alex", "age" : 18, "sex" : "男" }
{ "name" : "Alex", "age" : 17, "sex" : "男" }
</code></pre>
<blockquote>
<p>数组可以嵌套,即<code>{$type:90}</code></p>
<p><img src="https://img2018.cnblogs.com/blog/1458652/201908/1458652-20190805193813104-1126668796.png" alt="" loading="lazy"></p>
</blockquote>
<h4 id="24-数据操作函数">2.4. 数据操作函数</h4>
<h5 id="241-范围值">2.4.1 范围值</h5>
<p><code>db.collection.distinct(field)</code></p>
<p>功能:获取集合中某个域的值范围</p>
<p>参数:域名</p>
<p>返回值:取值的范围数组</p>
<pre><code># 查找class0的age域有哪些值
&gt; db.class0.distinct("age")
[ 17, 18, 20, 13, 21 ]
# 查找class0的sex域有哪些值
&gt; db.class0.distinct("sex")
[ "女", "男" ]
</code></pre>
<h5 id="242-格式化显示">2.4.2 格式化显示</h5>
<p><code>pretty()</code></p>
<p>功能:将查询结果格式化显示</p>
<pre><code>&gt; db.class0.find({},{_id:0}).pretty()
{ "name" : "Lily", "age" : 17 }
{ "name" : "Lucy", "age" : 18, "sex" : "女" }
{ "name" : "Chancey", "age" : 17, "sex" : "女" }
{ "name" : "素心", "age" : 20, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Abby", "age" : 21, "sex" : "男" }
{ "name" : "Alex", "age" : 18, "sex" : "男" }
{ "name" : "Alex", "age" : 17, "sex" : "男" }
</code></pre>
<h5 id="243-限制显示">2.4.3 限制显示</h5>
<p><code>limit</code></p>
<p>功能:显示查询结果前n条</p>
<pre><code># 只显示前三条信息
&gt; db.class0.find({},{_id:0}).limit(3)
{ "name" : "Lily", "age" : 17 }
{ "name" : "Lucy", "age" : 18, "sex" : "女" }
{ "name" : "Chancey", "age" : 17, "sex" : "女" }
</code></pre>
<h5 id="244-跳页显示">2.4.4 跳页显示</h5>
<p><code>skip(n)</code></p>
<p>跳过前n条,显示后边的文档</p>
<pre><code>&gt; db.class0.find({},{_id:0}).skip(6)
{ "name" : "Abby", "age" : 21, "sex" : "男" }
{ "name" : "Alex", "age" : 18, "sex" : "男" }
{ "name" : "Alex", "age" : 17, "sex" : "男" }
</code></pre>
<h5 id="245-统计数量">2.4.5 统计数量</h5>
<p><code>count()</code></p>
<p>功能:统计查询结果数量</p>
<pre><code># 统计所有文档
&gt; db.class0.find({},{_id:0}).count()
9
</code></pre>
<h5 id="246-排序">2.4.6 排序</h5>
<p><code>sort({field:1/-1})</code></p>
<p>功能:对查找结果排序</p>
<p>参数:field表示排序的域,1升序、-1降序</p>
<pre><code>&gt; db.class0.find({},{_id:0}).skip(5).sort({age:1})
{ "name" : "Lucy", "age" : 18, "sex" : "女" }
{ "name" : "Alex", "age" : 18, "sex" : "男" }
{ "name" : "素心", "age" : 20, "sex" : "男" }
{ "name" : "Abby", "age" : 21, "sex" : "男" }

&gt; db.class0.find({},{_id:0}).skip(5).sort({age:-1})
{ "name" : "Chancey", "age" : 17, "sex" : "女" }
{ "name" : "Alex", "age" : 17, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
</code></pre>
<p>复合排序</p>
<pre><code>&gt; db.class0.find({},{_id:0}).skip(5).sort({age:-1,name:-1})
{ "name" : "Chancey", "age" : 17, "sex" : "女" }
{ "name" : "Alex", "age" : 17, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
</code></pre>
<h5 id="247-函数连续调用">2.4.7 函数连续调用</h5>
<pre><code>&gt; db.class0.find({age:{$type:1}},{_id:0}).sort({afe:-1}).limit(3)
{ "name" : "Lily", "age" : 17 }
{ "name" : "Lucy", "age" : 18, "sex" : "女" }
{ "name" : "Chancey", "age" : 17, "sex" : "女" }
</code></pre>
<h5 id="248-序列号">2.4.8 序列号</h5>
<p>通过序列号直接获取文档集合中的某一个</p>
<pre><code># 获取文档集合的第一项
&gt; db.class0.find({},{_id:0}).sort({age:1})
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
</code></pre>
<h3 id="4-修改文档">4. 修改文档</h3>
<p><img src="assets/%E6%8F%92%E5%85%A5%E5%AF%B9%E6%AF%94.png" alt="" loading="lazy"></p>
<h4 id="41-修改函数">4.1 修改函数</h4>
<h6 id="412-updateone">4.1.2 updateOne</h6>
<p><code>db.collection.updateOne(query,update,upsert)</code></p>
<p>功能:修改第一个符合条件的文档</p>
<p>参数:查找条件、要修改的数据,同修改操作符一起使用、如果query没有筛选到文档,是否插入新的文档</p>
<blockquote>
<p>update 键值对文档,表达将数据修改为什么样子</p>
</blockquote>
<pre><code># 将name为小峰的age修改为16
db.class.updateOne({name:"小峰"},{$set:{age:16}})
</code></pre>
<blockquote>
<p>upset 如果没有匹配到文档,则决定是否创建新的文档,默认false</p>
</blockquote>
<pre><code>&gt; db.class.find({},{_id:0})
{ "name" : "小娅", "age" : 9, "sex" : "女", "hobby" : [ "draw", "football" ] }
&gt; db.class.updateOne({name:"waller"},{$set:{age:16}},{upsert:true})
{
      "acknowledged" : true,
      "matchedCount" : 0,
      "modifiedCount" : 0,
      "upsertedId" : ObjectId("5d43ec85e7bb29c632f30a0d")
}
&gt; db.class.find({},{_id:0})
{ "name" : "小娅", "age" : 9, "sex" : "女", "hobby" : [ "draw", "football" ] }
{ "name" : "waller", "age" : 16 }
</code></pre>
<h6 id="413-updatemany">4.1.3 updateMany</h6>
<p><code>db.collection.updateMany(query,update,upsert)</code></p>
<p>功能:修改所有符合条件的文档</p>
<p>参数:同updateOne</p>
<pre><code># 将字符串的年龄修改为数字类型的年龄18
&gt; db.class0.find({},{_id:0})
{ "name" : "waller", "age" : "\"20\"", "sex" : "男" }
{ "name" : "Mary", "age" : "\"18\"", "sex" : "男" }
&gt; db.class0.updateMany({age:{$type:2}},{$set:{age:18}})
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }
&gt; db.class0.find({},{_id:0})
{ "name" : "waller", "age" : 18, "sex" : "男" }
{ "name" : "Mary", "age" : 18, "sex" : "男" }
</code></pre>
<h6 id="414-update">4.1.4 update</h6>
<p><code>db.collection.update(query,update,upsert,multi)</code></p>
<p>功能:修改文档(可单一修改,也可多条修改)</p>
<p>参数:同、同、<code>upsert=true</code>等同于<code>{upsert:true}</code>、默认只修改一个文档(true为修改所有符合条件的文档)</p>
<blockquote>
<p>upsert和multi的格式直接填写true或者false</p>
</blockquote>
<pre><code>&gt; db.class0.update({name:"Jack"},{$set:{age:16}},true,true)
WriteResult({
      "nMatched" : 0,
      "nUpserted" : 1,
      "nModified" : 0,
      "_id" : ObjectId("5d43f0bee7bb29c632f30ab6")
})
&gt; db.class0.find({},{_id:0})
{ "name" : "waller", "age" : 18, "sex" : "男" }
{ "name" : "Mary", "age" : 18, "sex" : "男" }
{ "name" : "Jack", "age" : 16 }
</code></pre>
<blockquote>
<p>官方已经不推荐使用该方式插入数据,更加偏向于<code>updateOne</code>、<code>updateMany</code></p>
</blockquote>
<h6 id="415-findoneandupdate">4.1.5 findOneAndUpdate</h6>
<p><code>db.collection.findOneAndUpdate(query,update)</code></p>
<p>功能:查找到一个文档并修改</p>
<p>参数:查找条件、修改数据</p>
<p>返回值:修改之前的文档</p>
<pre><code>&gt; db.class0.find({},{_id:0})
{ "name" : "waller", "age" : 18, "sex" : "男" }
&gt; db.class0.findOneAndUpdate({name:"waller"},{$set:{age:19}})
{
      "_id" : ObjectId("5d43eef44f5000004c0054f2"),
      "name" : "waller",
      "age" : 18,
      "sex" : "男"
}
&gt; db.class0.find({},{_id:0})
{ "name" : "waller", "age" : 19, "sex" : "男" }
</code></pre>
<h6 id="416-findoneandreplace">4.1.6 findOneAndReplace</h6>
<p><code>db.collection.findOneAndReplace(query,doc)</code></p>
<p>功能:查找一个文档并替换之</p>
<p>参数:查找条件、新的文档</p>
<p>返回值:原来的文档</p>
<pre><code>&gt; db.class0.find({},{_id:0})
{ "name" : "Lily", "age" : 17 }
&gt; db.class0.findOneAndReplace({name:"Lily"},{name:"ame",age:17,sex:"女"})
{
      "_id" : ObjectId("5d42519a1ae0b26ac7985b89"),
      "name" : "Lily",
      "age" : 17
}
&gt; db.class0.find({},{_id:0})
{ "name" : "ame", "age" : 17, "sex" : "女" }
</code></pre>
<h4 id="42-修改器">4.2 修改器</h4>
<h5 id="421-set">4.2.1 set</h5>
<p><code>$set</code>:修改一个域的值或者增加一个域</p>
<pre><code># 修改一个域
&gt; db.class0.find({},{_id:0})
{ "name" : "小小", "age" : 18 }
{ "name" : "waller", "age" : 19, "sex" : "男" }
{ "name" : "Mary", "age" : 18, "sex" : "男" }
{ "name" : "Jack", "age" : 16 }
&gt; db.class0.updateOne({sex:{$exists:false}},{$set:{sex:"男"}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
&gt; db.class0.find({},{_id:0})
{ "name" : "小小", "age" : 18, "sex" : "男" }
{ "name" : "waller", "age" : 19, "sex" : "男" }
{ "name" : "Mary", "age" : 18, "sex" : "男" }
{ "name" : "Jack", "age" : 16 }

#修改多个域
@(shell):1:33
&gt; db.class0.find({},{_id:0})
{ "name" : "Lucy", "age" : 18, "sex" : "女" }
&gt; db.class0.updateOne({name:"Lucy"},{$set:{age:20,sex:"男"}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
&gt; db.class0.find({},{_id:0})
{ "name" : "Lucy", "age" : 20, "sex" : "男" }
</code></pre>
<h5 id="422-unset">4.2.2 unset</h5>
<p><code>$unset</code>删除一个域</p>
<pre><code>&gt; db.class0.find({},{_id:0})                                 )
{ "name" : "Lucy", "age" : 20, "sex" : "男" }
&gt; db.class0.updateOne({name:"Lucy"},{$unset:{sex:""}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
&gt; db.class0.find({},{_id:0})
{ "name" : "Lucy", "age" : 20 }
</code></pre>
<blockquote>
<p>当修改之后的域名为空时,即表示删除该域,注意使用<code>$unset</code></p>
</blockquote>
<h5 id="423-rename">4.2.3 rename</h5>
<p><code>$rename</code>重命名域</p>
<pre><code>&gt; db.class0.find({},{_id:0})
{ "name" : "ame", "age" : 17, "sex" : "女" }
{ "name" : "Lucy", "age" : 20 }
{ "name" : "Chancey", "age" : 17, "sex" : "女" }
{ "name" : "素心", "age" : 20, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Emmm", "age" : 13, "sex" : "男" }
{ "name" : "Abby", "age" : 21, "sex" : "男" }
{ "name" : "Alex", "age" : 18, "sex" : "男" }
{ "name" : "Alex", "age" : 17, "sex" : "男" }
{ "name" : "小小", "age" : 18, "sex" : "男" }
{ "name" : "waller", "age" : 19, "sex" : "男" }
{ "name" : "Mary", "age" : 18, "sex" : "男" }
{ "name" : "Jack", "age" : 16 }
{ "name" : "xx", "age" : 35 }
&gt; db.class0.updateMany({},{$rename:{sex:"gender"}})
{ "acknowledged" : true, "matchedCount" : 14, "modifiedCount" : 11 }
&gt; db.class0.find({},{_id:0})
{ "name" : "ame", "age" : 17, "gender" : "女" }
{ "name" : "Lucy", "age" : 20 }
{ "name" : "Chancey", "age" : 17, "gender" : "女" }
{ "name" : "素心", "age" : 20, "gender" : "男" }
{ "name" : "Emmm", "age" : 13, "gender" : "男" }
{ "name" : "Emmm", "age" : 13, "gender" : "男" }
{ "name" : "Abby", "age" : 21, "gender" : "男" }
{ "name" : "Alex", "age" : 18, "gender" : "男" }
{ "name" : "Alex", "age" : 17, "gender" : "男" }
{ "name" : "小小", "age" : 18, "gender" : "男" }
{ "name" : "waller", "age" : 19, "gender" : "男" }
{ "name" : "Mary", "age" : 18, "gender" : "男" }
{ "name" : "Jack", "age" : 16 }
{ "name" : "xx", "age" : 35 }
</code></pre>
<h5 id="424-setoneinsert">4.2.4 setOneInsert</h5>
<p><code>$setOneInsert</code>如果使用update*执行了插入文档操作,则作为插入的内容</p>
<pre><code># 如果执行了插入函数,则setOnInsert也会插入
&gt; db.class0.find({},{_id:0})
{ "name" : "ame", "age" : 17, "gender" : "女" }
{ "name" : "Davil", "age" : 18, "gender" : "m" }
&gt; db.class0.updateOne({name:"Davil"},{$set:{age:18},$setOnInsert:{gender:"m"}},{upsert:true})
{
      "acknowledged" : true,
      "matchedCount" : 0,
      "modifiedCount" : 0,
      "upsertedId" : ObjectId("5d43fb43e7bb29c632f30c02")
}
&gt; db.class0.find({},{_id:0})
{ "name" : "ame", "age" : 17, "gender" : "女" }
{ "name" : "Davil", "age" : 18, "gender" : "m" }
</code></pre>
<blockquote>
<p>uodate参数可以使用多个修改器</p>
<p>语句:<code>db.class0.updateOne({name:"Davil"},{$set:{age:18},$setOnInsert:{gender:"m"}},{upsert:true})</code></p>
<blockquote>
<p>如果执行了upsert,则会连同setOnInsert的内容也会插入</p>
</blockquote>
</blockquote>
<h5 id="425-inc">4.2.5 inc</h5>
<p><code>$inc</code>加法修改器</p>
<p>功能:指定域加指定数</p>
<pre><code># 给age通通加1
&gt; db.class.find({},{_id:0})
{ "name" : "波多", "age" : 33, "sex" : "女" }
{ "name" : "苍空", "age" : 36, "sex" : "女" }
{ "name" : "麻希", "age" : 30, "sex" : "女" }
&gt; db.class.updateMany({},{$inc:{age:1}})
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }
&gt; db.class.find({},{_id:0})
{ "name" : "波多", "age" : 34, "sex" : "女" }
{ "name" : "苍空", "age" : 37, "sex" : "女" }
{ "name" : "麻希", "age" : 31, "sex" : "女" }
</code></pre>
<blockquote>
<p>可以加整数、小数、负数、正数</p>
<p>注意:负数其实就是减法</p>
</blockquote>
<h5 id="426-mul">4.2.6 mul</h5>
<p><code>$mul</code> 乘法修改器</p>
<pre><code># 给所有人年龄乘以2
&gt; db.class.find({},{_id:0})
{ "name" : "波多", "age" : 34, "sex" : "女" }
{ "name" : "苍空", "age" : 37, "sex" : "女" }
{ "name" : "麻希", "age" : 31, "sex" : "女" }
&gt; db.class.updateMany({},{$mul:{age:0.5}})
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }
&gt; db.class.find({},{_id:0})
{ "name" : "波多", "age" : 17, "sex" : "女" }
{ "name" : "苍空", "age" : 18.5, "sex" : "女" }
{ "name" : "麻希", "age" : 15.5, "sex" : "女" }
</code></pre>
<blockquote>
<p>可以加整数、小数、负数、正数</p>
</blockquote>
<h5 id="427-max">4.2.7 max</h5>
<p><code>$max</code>修改某个域的值,如果小于指定值则改为指定值,大于则不变</p>
<pre><code>&gt; db.class.find({},{_id:0})
{ "name" : "波多", "age" : 17, "sex" : "女" }
{ "name" : "苍空", "age" : 18.5, "sex" : "女" }
{ "name" : "麻希", "age" : 15.5, "sex" : "女" }
# 如果age域小于30改为30,大于则不变
&gt; db.class.updateMany({sex:"女"},{$max:{age:30}})
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }
&gt; db.class.find({},{_id:0})
{ "name" : "波多", "age" : 30, "sex" : "女" }
{ "name" : "苍空", "age" : 30, "sex" : "女" }
{ "name" : "麻希", "age" : 30, "sex" : "女" }
</code></pre>
<blockquote>
<p>简记:能把小的改成大的</p>
</blockquote>
<h5 id="427-min">4.2.7 min</h5>
<p><code>$min</code>修改某个域的值,如果大于指定值则改为指定值,小于则不变</p>
<pre><code>&gt; db.class.find({},{_id:0})
{ "name" : "波多", "age" : 30, "sex" : "女" }
{ "name" : "苍空", "age" : 30, "sex" : "女" }
{ "name" : "麻希", "age" : 30, "sex" : "女" }
&gt; db.class.updateMany({sex:"女"},{$min:{age:18}})
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }
&gt; db.class.find({},{_id:0})
{ "name" : "波多", "age" : 18, "sex" : "女" }
{ "name" : "苍空", "age" : 18, "sex" : "女" }
{ "name" : "麻希", "age" : 18, "sex" : "女" }
</code></pre>
<blockquote>
<p>简记:能把大的改成小的</p>
</blockquote>
<h5 id="428-数组修改器">4.2.8 数组修改器</h5>
<h6 id="1-push">(1) push</h6>
<p><code>$push</code> 向数组中添加一项</p>
<pre><code># 给小红添加一项10分的成绩
&gt; db.class2.find({},{_id:0})
{ "name" : "小明", "age" : 10, "score" : [ 87, 69, 81 ] }
{ "name" : "小红", "age" : 9, "score" : [ 97, 89, 87 ] }
{ "name" : "小刚", "age" : 9, "score" : [ 90, 79, 90 ] }
&gt; db.class2.updateOne({name:"小红"},{$push:{score:10}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
&gt; db.class2.find({},{_id:0})
{ "name" : "小明", "age" : 10, "score" : [ 87, 69, 81 ] }
{ "name" : "小红", "age" : 9, "score" : [ 97, 89, 87, 10 ] }
{ "name" : "小刚", "age" : 9, "score" : [ 90, 79, 90 ] }
</code></pre>
<h6 id="2-pushall">(2) pushAll</h6>
<p><code>$pushAll</code> 向数组中添加多项</p>
<pre><code># 向小红添加88,98的成绩

</code></pre>
<h6 id="3-pull">(3) pull</h6>
<p><code>$pull</code> 从数组中删除某个值</p>
<pre><code># 删除小刚score中的90

</code></pre>
<h6 id="4pullall">(4)pullAll</h6>
<p><code>$puAll</code>同时删除数组中多个组</p>
<pre><code># 删除小刚的79,90
&gt; db.class2.find({},{_id:0})                         })
{ "name" : "小明", "age" : 10, "score" : [ 87, 69, 81 ] }
{ "name" : "小红", "age" : 9, "score" : [ 97, 89, 87, 10 ] }
{ "name" : "小刚", "age" : 9, "score" : [ 90, 79, 90 ] }
&gt; db.class2.updateOne({name:"小刚"},{$pullAll:{score:}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
&gt; db.class2.find({},{_id:0})                                 })
{ "name" : "小明", "age" : 10, "score" : [ 87, 69, 81 ] }
{ "name" : "小红", "age" : 9, "score" : [ 97, 89, 87, 10 ] }
{ "name" : "小刚", "age" : 9, "score" : [ ] }
</code></pre>
<h6 id="5-pop">(5) pop</h6>
<p><code>$pop</code>弹出数组中的一项</p>
<pre><code># 弹出小红的最后一项
&gt; db.class2.updateOne({name:"小红"},{$pop:{score:1}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
&gt; db.class2.find({},{_id:0})                     })
{ "name" : "小明", "age" : 10, "score" : [ 87, 69, 81 ] }
{ "name" : "小红", "age" : 9, "score" : [ 97, 89, 87 ] }
{ "name" : "小刚", "age" : 9, "score" : [ ] }
# 弹出小红的第一项
&gt; db.class2.updateOne({name:"小红"},{$pop:{score:-1}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
&gt; db.class2.find({},{_id:0})                        })
{ "name" : "小明", "age" : 10, "score" : [ 87, 69, 81 ] }
{ "name" : "小红", "age" : 9, "score" : [ 89, 87 ] }
{ "name" : "小刚", "age" : 9, "score" : [ ] }
</code></pre>
<blockquote>
<p>弹出类似于删除</p>
<p>但是弹出只能删除两端的内容</p>
<p>如果为1则弹出数组中最后一项,为-1则弹出第一项</p>
</blockquote>
<h6 id="6-addtoset">(6) addToSet</h6>
<p><code>addToSet</code> 向数组中添加一项,但不能和已有的数值重复</p>
<pre><code>&gt; db.class2.find({},{_id:0})                        })
{ "name" : "小明", "age" : 10, "score" : [ 87, 69, 81 ] }
{ "name" : "小红", "age" : 9, "score" : [ 89, 87 ] }
{ "name" : "小刚", "age" : 9, "score" : [ ] }
&gt; db.class2.updateOne({name:"小刚"},{$addToSet:{score:80}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
&gt; db.class2.find({},{_id:0})                           })
{ "name" : "小明", "age" : 10, "score" : [ 87, 69, 81 ] }
{ "name" : "小红", "age" : 9, "score" : [ 89, 87 ] }
{ "name" : "小刚", "age" : 9, "score" : [ 80 ] }
</code></pre>
<p>(7)each</p>
<p><code>$each</code>对多个值逐一操作</p>
<pre><code># 对90,10 都执行操作
&gt;db.class2.updateOne({name:"小红"},{$push:{$each:}})
</code></pre>
<p>(8) position</p>
<p><code>$position</code> 指定数组插入位置,配合$each使用</p>
<pre><code># 将90插入到索引1位置
&gt; db.class2.updateOne({name:"小刚"},{$push:{score:{$each:,$position:1}}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
&gt; db.class2.find({},{_id:0})
{ "name" : "小明", "age" : 10, "score" : [ 87, 69, 81 ] }
{ "name" : "小红", "age" : 9, "score" : [ 89, 87 ] }
{ "name" : "小刚", "age" : 9, "score" : [ 80, 90 ] }
</code></pre>
<p>(9) sort</p>
<p><code>$sort</code>给数组排序,配合$each使用</p>
<pre><code># 给score从按照降序排序
&gt; db.class2.updateOne({name:"小红"},{$push:{score:{$each:[],$sort:-1}}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
&gt; db.class2.find({},{_id:0})
{ "name" : "小明", "age" : 10, "score" : [ 87, 69, 81 ] }
{ "name" : "小红", "age" : 9, "score" : [ 89, 87 ] }
{ "name" : "小刚", "age" : 9, "score" : [ 80, 90 ] }
</code></pre>
<blockquote>
<p>-1为降序。1为升序</p>
</blockquote>
<h3 id="5-删除文档">5. 删除文档</h3>
<p><img src="https://img2018.cnblogs.com/blog/1458652/201908/1458652-20190805193915081-1527732070.png" alt="" loading="lazy"></p>
<h4 id="51-删除函数">5.1 删除函数</h4>
<h5 id="511-deleteone">5.1.1 deleteOne</h5>
<p><code>db.collection.deleteOne(query)</code></p>
<p>功能:删除第一个符合条件的文档</p>
<p>参数:筛选条件</p>
<pre><code># 删除第一个不存在性别域的文档
db.class.deleteOne({sex:{$exsits:false}})
</code></pre>
<h5 id="512-deletemany">5.1.2 deleteMany</h5>
<p><code>db.collection.deleteMany(query)</code></p>
<p>功能:删除所有</p>
<pre><code># 删除所有小于18岁的
&gt; db.class.find({},{_id:0})
{ "name" : "小红", "age" : 9, "sex" : "女", "hobby" : [ "dance", "draw" ] }
{ "name" : "小明", "age" : 24, "hobby" : [ "football", "sing" ] }
{ "name" : "小花", "age" : 36, "sex" : "女", "hobby" : [ "python", "computer" ] }
{ "name" : "小绿", "age" : 23, "sex" : "女", "hobby" : [ "computer", "draw" ] }
{ "name" : "小兰", "age" : 17, "sex" : "女", "hobby" : [ "sing", "draw" ] }
{ "name" : "小黄", "age" : 21, "sex" : "男", "hobby" : [ "python", "draw" ] }
{ "name" : "小黑", "age" : 17, "sex" : "男", "hobby" : [ "football", "pthon" ] }
{ "name" : "Chancey", "age" : 9, "sex" : "男", "hobby" : [ "computer", "python" ] }
{ "name" : "小娅", "age" : 10, "sex" : "女", "hobby" : [ "draw", "football" ] }
{ "name" : "小刚", "age" : 13, "sex" : "男", "hobby" : [ "draw", "football" ] }
&gt; db.class.deleteMany({age:{$lt:18}})
{ "acknowledged" : true, "deletedCount" : 12 }
&gt; db.class.find({},{_id:0})
{ "name" : "Chancey", "age" : 19, "sex" : "男", "hobby" : [ "draw", "dance", "sing" ] }
{ "name" : "小明", "age" : 24, "hobby" : [ "football", "sing" ] }
{ "name" : "小花", "age" : 36, "sex" : "女", "hobby" : [ "python", "computer" ] }
{ "name" : "小绿", "age" : 23, "sex" : "女", "hobby" : [ "computer", "draw" ] }
{ "name" : "小黄", "age" : 21, "sex" : "男", "hobby" : [ "python", "draw" ] }
</code></pre>
<blockquote>
<p>{}表示删除所有文档</p>
<p>即 db.class.deleteMany({})</p>
</blockquote>
<h5 id="513-remove">5.1.3 remove</h5>
<p><code>db.collection.remove(query,justOne)</code></p>
<p>功能:删除文档</p>
<p>参数:筛选条件、默认false,删除所有符合条件的文档,true只删除一个符合条件的文档</p>
<pre><code>
</code></pre>
<h5 id="514-findoneanddelete">5.1.4 findOneAndDelete</h5>
<p><code>db.collection.findOneAndDelete(query)</code></p>
<p>功能:查找一个文档并删除</p>
<p>参数:查找条件</p>
<p>返回:查找到的文档</p>
<pre><code># 查找Levi并删除
&gt;db.class0.findAndDelete({name:"Levi"})
</code></pre>
<h3 id="6-练习查询">6. 练习(查询)</h3>
<pre><code>"_id","age","hobby","name","sex"
"5d4294091bc9a34144301933","18","[ ""draw"", ""dance"", ""sing"" ]","Chancey","男"
"5d4296a91bc9a34144301934","18","[ ""draw"", ""python"" ]","小红","女"
"5d4296a91bc9a34144301935","23","[ ""sing"", ""football"" ]","小明","男"
"5d4296a91bc9a34144301936","35","[ ""python"", ""computer"" ]","小花","女"
"5d4296a91bc9a34144301937","22","[ ""computer"", ""draw"" ]","小绿","女"
"5d43dbb4a5755f70bb10b68a","16","[ ""sing"", ""draw"" ]","小兰","女"
"5d43dbb4a5755f70bb10b68b","20","[ ""python"", ""draw"" ]","小黄","男"
"5d43dbb4a5755f70bb10b68c","16","[ ""football"", ""pthon"" ]","小黑","男"
"5d43dbb4a5755f70bb10b68d","6","[ ""basketball"", ""computer"" ]","小峰","男"
"5d43dbb4a5755f70bb10b68e","9","[ ""basketball"", ""python"", ""football"" ]","小浩","男"
"5d43dbb4a5755f70bb10b68f","10","[ ""sing"", ""draw"", ""computer"" ]","小娜","女"
</code></pre>
<ol>
<li>
<p>查看班级中所有人信息</p>
<p><code> db.class.find({},{_id:0})</code></p>
</li>
<li>
<p>查看班级中年龄8岁的人员信息</p>
<p><code>db.class.find({age:{$eq:8}},{_id:0})</code></p>
<p><code>db.class.find({age:8},{_id:0})</code></p>
</li>
<li>
<p>查看年龄大于10岁的学生信息</p>
<p><code>db.class.find({age:{$gt:10}},{_id:0})</code></p>
</li>
<li>
<p>查看年龄在8-12岁之间的学生信息</p>
<p><code>db.class.find({$and:[{age:{$gt:7}},{age:{$lt:13}}]},{_id:0})</code></p>
<p><code>db.class.find($and:[{age:{$gte:8}},{age:{$lte:12}}],{_id:0})</code></p>
</li>
<li>
<p>查看年龄为9岁且喜欢画画的女生</p>
<p><code>db.class.find({age:9,sex:"女",hobby:"draw"},{_id:0})</code></p>
</li>
<li>
<p>查看年龄小于8岁大于12岁的同学</p>
<p><code>db.class.find({$or:[{age:{$lt:8}},{age:{$gt:12}}]},{_id:0})</code></p>
</li>
<li>
<p>查看年龄9岁或者11岁的学生信息</p>
<p><code>db.class.find({$or:[{age:9},{age:11}]},{_id:0})</code></p>
<p><code>db.class.find({age:{$in:}},{_id:0})</code></p>
</li>
<li>
<p>查看有两项兴趣爱好的学生</p>
<p><code>db.class.find({hobby:{$size:2}},{_id:0})</code></p>
</li>
<li>
<p>查找喜欢计算机的同学</p>
<p><code>db.class.find({hobby:"computer"},{_id:0})</code></p>
</li>
<li>
<p>查找既喜欢画画也喜欢跳舞的同学</p>
<p><code>db.class.find({$and:[{hobby:"draw"},{hobby:"dance"}]},{_id:0})</code></p>
<p><code>db.class.find({hobby:{$all:["draw","dance"]}},{_id:0})</code></p>
</li>
<li>
<p>统计兴趣爱好有3项的学生信息</p>
<p><code>db.class.find({hobby:{$size:3}},{_id:0})</code></p>
</li>
<li>
<p>找到班级中年龄第二大的同学</p>
<p><code>db.class.find({},{_id:0}).sort({age:-1})</code></p>
</li>
<li>
<p>找到班级中年龄最终小的三位女生</p>
<p><code>db.class.find({sex:'女'},{_id:0}).sort({age:1}).limit(3)</code></p>
</li>
</ol>
<h3 id="7-练习修改">7. 练习(修改)</h3>
<p>使用grade</p>
<pre><code>
</code></pre>
<ol>
<li>
<p>将小红年龄修改为8岁,兴趣爱好改为跳舞画画</p>
<p><code>db.class.updateOne({name:"小红"},{$set:{age:8,hobby:["dance","draw"]}})</code></p>
</li>
<li>
<p>小明多了一个兴趣爱好唱歌</p>
<p><code>db.class.updateOne({name:"小明"},{$push:{hobby:"sing"}})</code></p>
</li>
<li>
<p>小王兴趣爱好多个吹牛、打篮球</p>
<p><code> db.class.updateOne({name:"小王"},{$push:{hobby:["吹牛","basketball"]}})</code></p>
</li>
<li>
<p>小李兴趣增加跑步,但是确保不和以前的重复</p>
<p><code>db.class.updateOne({name:"小李"},{$addToSet:{hobby:{$each:["tunning","sing"]}}})</code></p>
</li>
<li>
<p>班级所有同学年龄增加1</p>
<p><code>db.class.updateMany({},{$inc:{age:1}})</code></p>
</li>
<li>
<p>删除小明的sex属性</p>
<p><code>db.class.updateOne({name:"小明"},{$unset:{sex:''}})</code></p>
</li>
<li>
<p>小李第一个兴趣爱好不要了</p>
<p><code>db.class.updateOne({name:"小明"},{$pop:{hobby:-1}})</code></p>
</li>
<li>
<p>小刚不喜欢画画了</p>
<p><code>db.class.update({name:"小刚"},{$pullAll:{hobby:["doraw","computer"]}})</code></p>
</li>
</ol>
<h3 id="8练习删除">8.练习(删除)</h3>
<ol>
<li>
<p>删除所有年龄小于8岁或者大于2岁的同学</p>
<p><code>db.class0.deleteMany({$or:[{age:{$lt:8}},{age:{$gt:12}}]})</code></p>
</li>
<li>
<p>删除兴趣爱好中除了画画或者跳舞的同学</p>
<p><code> db.class,deleteMany({hobby:{$nin:["draw","dance"]}})</code></p>
</li>
</ol>
<h2 id="九时间类型">九、时间类型</h2>
<h3 id="11-获取当前时间">1.1 获取当前时间</h3>
<p><code>new Date()</code>自动生成当前时间(标准时间)</p>
<pre><code>&gt; db.class1.find({},{_id:0})
{ "name" : "python入门", "date" : ISODate("2019-08-03T08:05:20.409Z") }
{ "name" : "python精通", "date" : ISODate("2019-08-03T08:13:59.146Z") }
</code></pre>
<h3 id="12-时间函数">1.2 时间函数</h3>
<p><code>ISODate()</code></p>
<p>功能:将指定的时间转换为标准时间存入</p>
<p>参数:默认同<code>new Date(0)</code>获取当前时间或者字符定制时间</p>
<pre><code># 传入指定的时间
&gt; db.class1.insert({name:"python从入门到精通",date:ISODate()}))
WriteResult({ "nInserted" : 1 })
&gt; db.class1.find({},{_id:0})
{ "name" : "python入门", "date" : ISODate("2019-08-03T08:05:20.409Z") }
{ "name" : "python精通", "date" : ISODate("2019-08-03T08:13:59.146Z") }
{ "name" : "python从入门到精通", "date" : ISODate("2019-08-03T08:17:31.467Z") }
&gt; db.class1.insert({name:"疯狂的python",date:ISODate("2019-01-01 08:08:08")})
WriteResult({ "nInserted" : 1 })
&gt; db.class1.find({},{_id:0})
{ "name" : "python入门", "date" : ISODate("2019-08-03T08:05:20.409Z") }
{ "name" : "python精通", "date" : ISODate("2019-08-03T08:13:59.146Z") }
{ "name" : "python从入门到精通", "date" : ISODate("2019-08-03T08:17:31.467Z") }
{ "name" : "疯狂的python", "date" : ISODate("2019-01-01T08:08:08Z") }
</code></pre>
<blockquote>
<p>"2019-01-01 08:08:08"</p>
<p>"20190101 8:8:8"</p>
<p>"20190101"</p>
</blockquote>
<h3 id="13-时间戳">1.3 时间戳</h3>
<p><code>valueOf()</code></p>
<p>功能:将标准化时间转化为时间戳</p>
<pre><code># 将标准时间转换为时间戳
&gt; db.class1.insertOne({book:"Python涅槃",date:ISODate().valueOf()})
{
      "acknowledged" : true,
      "insertedId" : ObjectId("5d45443bac70897becf59e7e")
}
&gt; db.class1.find({},{_id:0})
{ "name" : "python入门", "date" : ISODate("2019-08-03T08:05:20.409Z") }
{ "name" : "python精通", "date" : ISODate("2019-08-03T08:13:59.146Z") }
{ "name" : "python从入门到精通", "date" : ISODate("2019-08-03T08:17:31.467Z") }
{ "name" : "疯狂的python", "date" : ISODate("2019-01-01T08:08:08Z") }
{ "book" : "Python涅槃", "date" : 1564820539435 }
</code></pre>
<h3 id="14-null类型">1.4 null类型</h3>
<p>值:<code>null</code></p>
<p>含义:空</p>
<blockquote>
<p>表示某个域的值为空</p>
</blockquote>
<pre><code>&gt; db.class1.insertOne({book:"python web",price:null})
{
      "acknowledged" : true,
      "insertedId" : ObjectId("5d454529ac70897becf59e7f")
}
&gt; db.class1.find({},{_id:0})
{ "book" : "python web", "price" : null }
</code></pre>
<blockquote>
<p>在查找的时候,如果用price域查找,没有price域的也会被查找出来</p>
</blockquote>
<pre><code># 查找到price域为null或者没有该域的
&gt; db.class1.find({price:null},{_id:0})
{ "name" : "python入门", "date" : ISODate("2019-08-03T08:05:20.409Z") }
{ "name" : "python精通", "date" : ISODate("2019-08-03T08:13:59.146Z") }
{ "name" : "python从入门到精通", "date" : ISODate("2019-08-03T08:17:31.467Z") }
{ "name" : "疯狂的python", "date" : ISODate("2019-01-01T08:08:08Z") }
{ "book" : "Python涅槃", "date" : 1564820539435 }
{ "book" : "python web", "price" : null }
</code></pre>
<h3 id="15-内部文档">1.5 内部文档</h3>
<p>也称<code>Object</code>类型</p>
<pre><code>&gt; db.calss3.insertOne({"book":"xi you ji ",intro:{author:"wu cheng en",price:38.6,publication:"China"}})
{
      "acknowledged" : true,
      "insertedId" : ObjectId("5d45476cac70897becf59e80")
}
&gt; db.calss3.insertOne({"book":"san guo yan yi",intro:{author:"luo guan zhong",price:42.6,publication:"China"}})
{
      "acknowledged" : true,
      "insertedId" : ObjectId("5d45478aac70897becf59e81")
}
&gt; db.calss3.insertOne({"book":"shui hu zhuan",intro:{author:"shi nai an",price:48,publication:"China"}})
{
      "acknowledged" : true,
      "insertedId" : ObjectId("5d4547a3ac70897becf59e82")
}
&gt; db.calss3.find({},{_id:0})
{ "book" : "xi you ji ", "intro" : { "author" : "wu cheng en", "price" : 38.6, "publication" : "China" } }
{ "book" : "san guo yan yi", "intro" : { "author" : "luo guan zhong", "price" : 42.6, "publication" : "China" } }
{ "book" : "shui hu zhuan", "intro" : { "author" : "shi nai an", "price" : 48, "publication" : "China" } }
</code></pre>
<p>定义:文档中某个域的值为内部文档,则该值为<code>Object</code>类型数据</p>
<p>使用方法:当使用内部文档某个域的值时,需要采用<code>"外部域.内部域"</code>的方法,此时,该格式需要用引号表示为字符串</p>
<pre><code># 内部文档查找
&gt; db.calss3.find({"intro.author":"wu cheng en"},{_id:0})
{ "book" : "xi you ji ", "intro" : { "author" : "wu cheng en", "price" : 38.6, "publication" : "China" } }
&gt; db.calss3.find({"intro.publication":"China"},{_id:0})
{ "book" : "xi you ji ", "intro" : { "author" : "wu cheng en", "price" : 38.6, "publication" : "China" } }
{ "book" : "san guo yan yi", "intro" : { "author" : "luo guan zhong", "price" : 42.6, "publication" : "China" } }
{ "book" : "shui hu zhuan", "intro" : { "author" : "shi nai an", "price" : 48, "publication" : "China" } }

# 内部文档修改
&gt; db.calss.updateOne({book:"xi you ji "},{$set:{"intro.price":42}})
{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0 }
&gt; db.calss3.find({},{_id:0})
{ "book" : "xi you ji ", "intro" : { "author" : "wu cheng en", "price" : 38.6, "publication" : "China" } }
{ "book" : "san guo yan yi", "intro" : { "author" : "luo guan zhong", "price" : 42.6, "publication" : "China" } }
{ "book" : "shui hu zhuan", "intro" : { "author" : "shi nai an", "price" : 48, "publication" : "China" } }
</code></pre>
<h3 id="16-练习">1.6 练习</h3>
<ol>
<li>
<p>将小红爱好的第二项变为唱歌</p>
<p><code>db.class.updateOne({name:"xiao hong"},{$set:{'hobby.1':"sing"}})</code></p>
</li>
<li>
<p>给小王增加一个域</p>
<p>备注:{民族:“回族”,习俗:“注意饮食禁忌”}</p>
<p><code>db.class.updateOne({name:"xiao hong"},{$set:{'备注':{"民族":"回族","习俗":"注意饮食禁忌"}}})</code></p>
</li>
<li>
<p>修改小王的备注域,增加一项</p>
<p>宗教:“伊斯兰”</p>
<p><code>db.class.updateOne({name:"小王"},{$set:{"备注.宗教":"伊斯兰"}})</code></p>
</li>
</ol>
<h2 id="十-索引">十、 索引</h2>
<h3 id="1概述">1.概述</h3>
<p><img src="https://img2018.cnblogs.com/blog/1458652/201908/1458652-20190805193959471-1310284016.png" alt="" loading="lazy"></p>
<h4 id="11-定义">1.1 定义</h4>
<p>建立文档所在位置的查找清单,使用索引可以方便的快速查找,减少遍历次数,提高查找效率</p>
<h4 id="12-索引约束">1.2 索引约束</h4>
<ul>
<li>数据量很小的时候不需要创建索引</li>
<li>创建索引会增加磁盘的使用空间</li>
<li>对数据库操作大多是写操作而不是读操作的时候不宜创建索引</li>
</ul>
<h3 id="2创建索引">2.创建索引</h3>
<h4 id="21-createindex">2.1 createIndex</h4>
<p><code>db.collection.createIndex()</code></p>
<p>功能:创建索引</p>
<p>参数:索引域和索引选项</p>
<pre><code>#为name创建索引
&gt; db.class0.createIndex({name:1})
{
      "createdCollectionAutomatically" : false,
      "numIndexesBefore" : 1,
      "numIndexesAfter" : 2,
      "ok" : 1
}

# 指定索引名称创建
&gt; db.class0.createIndex({age:1},{name:"ageIndex"})
{
      "createdCollectionAutomatically" : false,
      "numIndexesBefore" : 2,
      "numIndexesAfter" : 3,
      "ok" : 1
}
</code></pre>
<blockquote>
<p>参数说明:1为正向索引,-1为反向索引</p>
</blockquote>
<h4 id="22-ensureindex">2.2 ensureIndex</h4>
<p><code>db.collection.ensureIndex()</code>不常用</p>
<h4 id="23-createindexes">2.3 createIndexes</h4>
<p><code>createIndexes([{},{},{},...])</code>不常用</p>
<p>同时创建多个索引</p>
<h3 id="3查看索引">3.查看索引</h3>
<p><code>db.collection.getIndexes()</code></p>
<p>功能:查看索引</p>
<pre><code>
# 查看索引
&gt; db.class0.getIndexes()
[
      {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "stu.class0"
      },
      {
                "v" : 2,
                "key" : {
                        "name" : 1
                },
                "name" : "name_1",
                "ns" : "stu.class0"
      },
                },
      {
                "v" : 2,
                "key" : {
                        "age" : 1
                },
                "name" : "ageIndex",
                "ns" : "stu.class0"
      }
]
</code></pre>
<blockquote>
<p>在创建文档的时候,系统会自动为<code>_id</code>创建索引,所以这里出现两个索引</p>
</blockquote>
<h3 id="4删除索引">4.删除索引</h3>
<h4 id="41-dropindex">4.1 dropIndex</h4>
<p><code>db.collection.dropIndex(index or name)</code></p>
<p>功能:删除一个索引</p>
<p>参数:索引名称或者索引键值对</p>
<pre><code># 通过索引键值对删除
&gt; db.class0.dropIndex({age:1})
{ "nIndexesWas" : 3, "ok" : 1 }
&gt; db.class0.getIndexes()
[
      {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "stu.class0"
      },
      {
                "v" : 2,
                "key" : {
                        "name" : 1
                },
                "name" : "name_1",
                "ns" : "stu.class0"
      }
]

# 通过索引名删除
&gt; db.class0.dropIndex("name_1") # 注意没有{}
{ "nIndexesWas" : 2, "ok" : 1 }
&gt; db.class0.getIndexes()
[
      {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "stu.class0"
      }
]
</code></pre>
<blockquote>
<p>注意这里使用键值对时用<code>{}</code>,使用索引名时用<code>()</code></p>
</blockquote>
<h4 id="42-dropindexes">4.2 dropIndexes</h4>
<p><code>db.collection.dropIndexes</code></p>
<p>删除所有索引</p>
<pre><code>&gt; db.class0.dropIndexes()
{
      "nIndexesWas" : 2,
      "msg" : "non-_id indexes dropped for collection",
      "ok" : 1
}
&gt; db.class0.getIndexes()
[
      {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "stu.class0"
      }
]
</code></pre>
<blockquote>
<p>该操作不会删除<code>_id_</code>索引</p>
</blockquote>
<h3 id="5-其他索引">5. 其他索引</h3>
<h4 id="51-复合索引">5.1 复合索引</h4>
<p>根据多个域创建索引</p>
<pre><code>&gt; db.class0.createIndex({name:1,age:-1})
{
      "createdCollectionAutomatically" : false,
      "numIndexesBefore" : 1,
      "numIndexesAfter" : 2,
      "ok" : 1
}
&gt; db.class0.getIndexes()
[
      {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "stu.class0"
      },
      {
                "v" : 2,
                "key" : {
                        "name" : 1,
                        "age" : -1
                },
                "name" : "name_1_age_-1",
                "ns" : "stu.class0"
      }
]
</code></pre>
<blockquote>
<p>只需要填入多个键值对即可</p>
</blockquote>
<h4 id="52-object数组索引">5.2 Object/数组索引</h4>
<p>如果对object域或者数组域创建索引则针对object或者数组中的某一个元素的查询也是索引查询</p>
<pre><code># 如果岁intro创建了索引,则该查找也是索引查找
db.class3.find({"intro.author":"曹雪芹"})
</code></pre>
<h4 id="53-唯一索引">5.3 唯一索引</h4>
<p>要求创建索引的域不能有重复值</p>
<pre><code># 已经存在的索引则不会再创建
&gt; db.class0.getIndexes()
[
      {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "stu.class0"
      }
]
</code></pre>
<h4 id="54-稀疏索引">5.4 稀疏索引</h4>
<p>如果创建的稀疏索引则会对没有索引域的文档忽略</p>
<pre><code>&gt;db.calss0.createIndex({name:1},{sparse:true,name:"Age"})

</code></pre>
<h2 id="十一-聚合操作">十一、 聚合操作</h2>
<p>对文档进行数据整理统计,得到统计结果</p>
<h3 id="1聚合函数">1.聚合函数</h3>
<h4 id="11-aggregate">1.1 aggregate</h4>
<p><code>db.collection.aggregate(aggr)</code></p>
<p>功能:执行聚合操作</p>
<p>参数:聚合条件,配合聚合操作符使用</p>
<h4 id="12-聚合操作符">1.2 聚合操作符</h4>
<h5 id="121-分组聚合">1.2.1 分组聚合</h5>
<p><code>$group</code> 需要配合统计操作符</p>
<blockquote>
<p>统计求和 <code>$sum</code>传的可以是整数、文档</p>
</blockquote>
<pre><code># 统计男生、女生的年龄之和
&gt; db.class0.aggregate({$group:{_id:'$gender',num:{$sum:1}}})
{ "_id" : "男", "num" : 9 }
{ "_id" : "女", "num" : 2 }

#按性别分组,求男生女生的平均年龄
&gt; db.class0.aggregate({$group:{_id:"$gender",num:{$avg:"$age"}}})
{ "_id" : "男", "num" : 17.444444444444443 }
{ "_id" : "女", "num" : 17 }

</code></pre>
<p>求最大最小值</p>
<p><code>$max / $min</code></p>
<pre><code>#按照性别分组,求每组的最大值、最小值
&gt; db.class0.aggregate({$group:{_id:"$gender",num:{$max:"$age"}}})
{ "_id" : "男", "num" : 21 }
{ "_id" : "女", "num" : 17 }
&gt; db.class0.aggregate({$group:{_id:"$gender",num:{$min:"$age"}}})
{ "_id" : "男", "num" : 13 }
{ "_id" : "女", "num" : 17 }
</code></pre>
<p>求第一个值或最后一个值</p>
<p><code>$first / $last</code></p>
<pre><code># 按照性别分组,求每组的第一个、最后一个值
&gt; db.class0.aggregate({$group:{_id:"$gender",num:{$first:"age"}}})
{ "_id" : "男", "num" : "age" }
{ "_id" : "女", "num" : "age" }
&gt; db.class0.aggregate({$group:{_id:"$gender",num:{$last:"age"}}})
{ "_id" : "男", "num" : "age" }
{ "_id" : "女", "num" : "age" }
</code></pre>
<h5 id="122-数据筛选">1.2.2 数据筛选</h5>
<p><code>$match</code></p>
<p>match的基本操作同query</p>
<pre><code># 筛选年龄为18 的文档
&gt; db.class0.aggregate({$match:{age:18}})
{ "_id" : ObjectId("5d42a1621bc9a3414430193b"), "name" : "Alex", "age" : 18, "gender" : "男" }
{ "_id" : ObjectId("5d43edc8a5755f70bb10b692"), "name" : "小小", "age" : 18, "gender" : "男" }
{ "_id" : ObjectId("5d43ef0f4f5000004c0054f3"), "name" : "Mary", "age" : 18, "gender" : "男" }
{ "_id" : ObjectId("5d43fb43e7bb29c632f30c02"), "name" : "Davil", "age" : 18, "gender" : "m" }

# 筛选年龄大于18的文档
&gt; db.class0.aggregate({$match:{age:{$gt:18}}})
{ "_id" : ObjectId("5d428df01bc9a3414430192e"), "name" : "Lucy", "age" : 20 }
{ "_id" : 1, "name" : "素心", "age" : 20, "gender" : "男" }
{ "_id" : ObjectId("5d42a08d1bc9a3414430193a"), "name" : "Abby", "age" : 21, "gender" : "男" }
{ "_id" : ObjectId("5d43eef44f5000004c0054f2"), "name" : "waller", "age" : 19, "gender" : "男" }
{ "_id" : ObjectId("5d43f65ea5755f70bb10b693"), "name" : "xx", "age" : 35 }
</code></pre>
<p><code>$limit</code></p>
<p>获取集合中前几条文档</p>
<pre><code># 获取前三条文档
&gt; db.class0.aggregate({$limit:3})
{ "_id" : ObjectId("5d42519a1ae0b26ac7985b89"), "name" : "ame", "age" : 17, "gender" : "女" }
{ "_id" : ObjectId("5d428df01bc9a3414430192e"), "name" : "Lucy", "age" : 20 }
{ "_id" : ObjectId("5d428ee01bc9a3414430192f"), "name" : "Chancey", "age" : 17, "gender" : "女" }
</code></pre>
<p><code>$skip</code> 跳过前几个文档</p>
<pre><code># 对查找结果跳过前10条
&gt; db.class0.aggregate({$skip:10})
{ "_id" : ObjectId("5d43eef44f5000004c0054f2"), "name" : "waller", "age" : 19, "gender" : "男" }
{ "_id" : ObjectId("5d43ef0f4f5000004c0054f3"), "name" : "Mary", "age" : 18, "gender" : "男" }
{ "_id" : ObjectId("5d43f0bee7bb29c632f30ab6"), "name" : "Jack", "age" : 16 }
{ "_id" : ObjectId("5d43f65ea5755f70bb10b693"), "name" : "xx", "age" : 35 }
{ "_id" : ObjectId("5d43fb43e7bb29c632f30c02"), "name" : "Davil", "age" : 18, "gender" : "m" }
</code></pre>
<p><code>$sort</code> 对文档排序</p>
<pre><code>&gt; db.class0.aggregate({$sort:{age:1}})
{ "_id" : ObjectId("5d42a06d1bc9a34144301938"), "name" : "Emmm", "age" : 13, "gender" : "男" }
{ "_id" : ObjectId("5d42a08d1bc9a34144301939"), "name" : "Emmm", "age" : 13, "gender" : "男" }
{ "_id" : ObjectId("5d43f0bee7bb29c632f30ab6"), "name" : "Jack", "age" : 16 }
{ "_id" : ObjectId("5d42519a1ae0b26ac7985b89"), "name" : "ame", "age" : 17, "gender" : "女" }
{ "_id" : ObjectId("5d428ee01bc9a3414430192f"), "name" : "Chancey", "age" : 17, "gender" : "女" }
{ "_id" : ObjectId("5d42a3bb1bc9a3414430193c"), "name" : "Alex", "age" : 17, "gender" : "男" }
{ "_id" : ObjectId("5d42a1621bc9a3414430193b"), "name" : "Alex", "age" : 18, "gender" : "男" }
</code></pre>
<h3 id="2聚合管道">2.聚合管道</h3>
<p><code>db.class0.aggregate([{},{},{},...])</code></p>
<p>将前一个聚合产生的结果交给最后一个聚合继续操作,直到最后结果</p>
<pre><code># 将sort出来的结果给limit操作
&gt; db.class0.aggregate([{$sort:{age:-1}},{$limit:3}])
{ "_id" : ObjectId("5d43f65ea5755f70bb10b693"), "name" : "xx", "age" : 35 }
{ "_id" : ObjectId("5d42a08d1bc9a3414430193a"), "name" : "Abby", "age" : 21, "gender" : "男" }
{ "_id" : 1, "name" : "素心", "age" : 20, "gender" : "男" }
</code></pre>
<blockquote>
<p>聚合管道可以有多个聚合函数共同操作</p>
</blockquote>
<pre><code># 查看名字重复的次数
&gt; db.class0.aggregate([{$group:{_id:"$name",num:{$sum:1}}},{$match:{num:{$gt:1}}}])
{ "_id" : "Emmm", "num" : 2 }
{ "_id" : "Alex", "num" : 2 }
</code></pre>
<h3 id="3聚合操作符">3.聚合操作符</h3>
<p><code>$project</code></p>
<p>选择显示的域(值的写法同field参数)</p>
<pre><code># 筛选结果不显示_id,仅仅显示name和age
&gt; db.class0.aggregate([{$match:{}},{$project:{_id:0,name:1,age:1}}])
{ "name" : "素心", "age" : 20 }
{ "name" : "ame", "age" : 17 }
{ "name" : "Lucy", "age" : 20 }
{ "name" : "Chancey", "age" : 17 }
</code></pre>
<h3 id="4-练习">4. 练习</h3>
<ol>
<li>
<p>将所有男生按照年龄升序排序,结果不显示_id</p>
<p><code>db.class0.aggregate([$match:{gender:"男"},{$sort:{age:1}},{$project:{_id:0}}])</code></p>
</li>
<li>
<p>将所有喜欢画画的女生按照年龄排序,取年龄最后的三个,只显示姓名、年龄、爱好</p>
<p><code>db.class0.aggregate([{$match:{hobby:"graw",sex:"女"}},{$sort:{age:1}},{$limit:3},{$project:{_id:0,name:1,hobby:1}}])</code></p>
</li>
</ol>
<h2 id="十二固定集合">十二、固定集合</h2>
<p>指的是MongoDB中创建固定大小的集合,称之为固定集合</p>
<blockquote>
<p>特点:</p>
<ol>
<li>如果在固定集合中强行插入数据,早期的数据将会被淘汰,从而插入新的数据</li>
<li>可以控制集合大小</li>
<li>数据插入、查找速度快</li>
</ol>
<p>使用:日志处理,临时缓存</p>
</blockquote>
<h3 id="1-创建">1. 创建</h3>
<p><code>db.createCollection(collection,{capped:true,size:10000,max:20})</code></p>
<p>capped:reuw 表示创建一个固定集合</p>
<p>size:10000 表示固定集合的大小</p>
<p>max 表示固定集合可存放的文档数量</p>
<pre><code># 创建固定集合log,最多存放三条文档
&gt; db.createCollection("log",{capped:true,size:1000,max:3})
{ "ok" : 1 }
&gt; show collections
log
</code></pre>
<h3 id="2-插入数据">2. 插入数据</h3>
<pre><code># 已经插入了三条数据
&gt; db.log.find({},{_id:0,date:0})
{ "status" : "400", "address" : "192.168.1.5" }
{ "status" : "500", "address" : "192.168.1.5" }
{ "status" : "501", "address" : "192.168.1.5" }

# 再次尝试添加数据,返回true
&gt; db.log.insertOne({status:"502",address:"192.168.1.5",date:Date})
{
        "acknowledged" : true,
        "insertedId" : ObjectId("5d4791418615e4157d3980b6")
}

# 查看时,前边的400不见了,多出来了502
&gt; db.log.find({},{_id:0,date:0})
{ "status" : "500", "address" : "192.168.1.5" }
{ "status" : "501", "address" : "192.168.1.5" }
{ "status" : "502", "address" : "192.168.1.5" }
</code></pre>
<h2 id="十三文件存储">十三、文件存储</h2>
<p>MongoDB提供了一些存储文件的方式</p>
<h3 id="1-存储文件路径">1. 存储文件路径</h3>
<p>将本地的文件所在的路径以字符串存入到数据库里</p>
<blockquote>
<p>优点:操作简单,节省空间</p>
<p>缺点:当数据库或者文件发生变化的时候需要球盖数据库</p>
</blockquote>
<h3 id="2-存储文件本身">2. 存储文件本身</h3>
<p>将文件转换为二进制存储到数据库里</p>
<blockquote>
<p>优点:文件绑定数据库,不易丢失</p>
<p>缺点:占用数据库空间大,文件存取效率低</p>
</blockquote>
<h4 id="12-大文件存储">1.2 大文件存储</h4>
<p><strong>GridFS文件存储方案</strong></p>
<p>目的:更加方便的存取MongoDB中的大文件(&gt;16M)</p>
<p>说明:</p>
<pre><code>1. MongoDB数据库中创建两个集合共同存储文件
2. fs.files集合中为每个文件建立一个信息文档,存储文件的基本信息
3. fs.chunks集合中每个文档建立与fs.files的关系,并将文件分块存储
</code></pre>
<p>方法:</p>
<p>(1) 存储</p>
<p><code>mongofiles -d dbname put file</code></p>
<pre><code class="language-bash"># 将demo.mp4 存储到数据库中
# mongofiles -d grid put demo.mp4
2019-08-05T10:35:35.908+0800        connected to: localhost
added file: demo.mp4
</code></pre>
<p><code>db.fs.files.find()</code> #查看文件信息</p>
<p><code>db.fs.chunks.find()</code></p>
<blockquote>
<p>files和chunks的files_id域的值是一样的,以此来确定两个集合之间的关联</p>
</blockquote>
<p>(2) 提取</p>
<p><code>mongofiles -d dbname get file</code></p>
<pre><code># ls
# mongofiles -d grid get demo.mp4 # 从数据库中获取demo.mp4 文件
2019-08-05T10:52:06.082+0800        connected to: localhost
finished writing to demo.mp4
# ls
demo.mp4
</code></pre>
<p>对大文件的存储提取方便,但是读写效率仍然比较低,不建议用来存储小文件</p>
<h4 id="13-小文件存储">1.3 小文件存储</h4>
<p>pass</p>
<h2 id="十四mongo-shell">十四、mongo shell</h2>
<p>对JavaScript支持,mongo shell就是用JavaScript编写的,所以可以使用基本的js代码</p>
<ul>
<li>mongo shell 界面中支持基本的js代码</li>
<li>通过js处理mongo的一些数据逻辑</li>
</ul>
<h2 id="十五python操作mongodb">十五、python操作MongoDB</h2>
<p>使用第三库<code>pymongo</code>,安装方法不再赘述</p>
<h3 id="1步骤">1.步骤</h3>
<p>导入pymongo</p>
<h4 id="11-连接">1.1 连接</h4>
<pre><code class="language-python">from pymongo import MongoClient
conn = MongoClient("IP",27017) # 实现连接
</code></pre>
<h4 id="12-选择数据库">1.2 选择数据库</h4>
<pre><code class="language-python">db = conn.stu #选择数据库
myset = db.class0 # 选择集合
</code></pre>
<h4 id="13-操作">1.3 操作</h4>
<blockquote>
<p>通过集合对象调用接口完成数据操作</p>
</blockquote>
<p>文档 --&gt; 字典</p>
<p>数字 --&gt; 列表</p>
<p>布尔 --&gt; python</p>
<p>null --&gt; Mome</p>
<p>操作符 --&gt; 字符串形式原样书写</p>
<p><span class="math inline">\(lt                        "\)</span>lt"</p>
<pre><code class="language-python">from pymongo import MongoClient

# 创建数据库连接
conn = MongoClient('127.0.0.1',27017)

# 床架数据库对象和集合对象
db = conn.stu
myset = db.class4 # 如果不存在该文档,则创建
</code></pre>
<h5 id="131-插入操作">1.3.1 插入操作</h5>
<p><code>insert_one()</code>插入一条文档</p>
<p><code>insert_many()</code> 插入多条文档</p>
<p><code>insert()</code> 插入一条或者多条</p>
<p><code>save()</code> 插入文档,如果_id重复就会覆盖</p>
<pre><code class="language-python">myset.insert_one({"name":"杨幂","King":"Chancey"})
myset.insert_many([{"name":"刘诗诗","King":"吴奇隆"},{"name":"杨紫","King":"张一山"}])
myset.insert({"name":"乔碧萝","King":"菜虚鲲"})
myset.insert([{"name":"林志玲","King":"黑泽良平"},{"name":"柳岩","King":"小岳岳"}])

myset.save({"_id":1,"name":"郑爽","King":"张翰"})
myset.save({"_id":1,"name":"郑爽","King":"慕容云海"})
# 返回结果查看,张翰被替换成了慕容云海
</code></pre>
<h5 id="132-查找操作">1.3.2 查找操作</h5>
<h6 id="find">find</h6>
<p><code>find()</code>查找所有</p>
<p>功能:查找所有文档</p>
<p>参数:形式同mongo中的 find</p>
<p>返回值:查找结果的游标对象</p>
<blockquote>
<p>cursor游标对象属性</p>
<ul>
<li>通过迭代获取每个查找的文档结果</li>
<li>通过调用属性方法对结果进一步操作</li>
</ul>
<blockquote>
<p>next()</p>
<p>limit()</p>
<p>skip()</p>
<p>count()</p>
<p>sort() 书写方法不一样,类似于sort([("age",1),("name",1)])</p>
</blockquote>
<p>要得到具体的文档内容,需要遍历cursor</p>
<pre><code class="language-python">cursor = myset.find({},{'_id':0})
# 循环遍历,得到每一个结果都是文档字典
for i in cursor:
    print(i["name"],'------',i["King"])
</code></pre>
</blockquote>
<pre><code class="language-python"># 所有的特殊操作符均加引号执行
cursor = myset.find({},{'_id':0})

# 循环遍历,得到每一个结果都是文档字典
for i in cursor:
    print(i["name"],'------',i["King"])

print(cursor.next()) #获取游标的下一个结果

# 调用skip、limit之后得到的仍然是游标对象,必须保证该游标对象没有遍历过
for i in cursor.skip(1).limit(3):
    print(i)

# 按照king排序
for i in cursor.sort([("King",1)]):
    print(i)
</code></pre>
<blockquote>
<p>注意:</p>
<ol>
<li>
<p>调用limit、skip、sort时游标必须没有遍历过</p>
</li>
<li>
<p>sort写法不同</p>
<p>{age:1,name:1} --&gt; [('age',1),('name',1)]</p>
</li>
</ol>
</blockquote>
<h6 id="find_one">find_one</h6>
<p><code>find_one()</code>查找一个文档</p>
<p>功能:查找一个文档</p>
<p>参数:同find</p>
<p>返回值:文档字典</p>
<pre><code class="language-python">r = myset.find_one({"King":"菜虚鲲"},{"_id":0})
print(r)
</code></pre>
<h5 id="133-修改文档">1.3.3 修改文档</h5>
<p><code>update_one()</code>修改一个文档</p>
<p><code>update_many()</code>修改多个文档</p>
<p><code>update()</code>修改一个或多个文档</p>
<pre><code class="language-python">#***************   find   ***************
myset.update_one({"King":"刘恺威"},{"$set":{"king_name":"chancey"}})
myset.update_many({"King":"菜虚鲲"},{"$set":{"king_name":"蔡徐坤"}})
myset.update({"King":"张一山"},{"$set":{"king_name":"张两山"}})
myset.update({"king_name":"张两山"},{"$set":{"king_name":"张三山"}},multi=True)
myset.update({"king_name":"张两山"},{"$set":{"king_name":"张三山"}},upsert=True)
</code></pre>
<h5 id="133删除操作">1.3.3删除操作</h5>
<p><code>delete_one</code>删除一个文档</p>
<p><code>delete_many</code>删除多个文档</p>
<p><code>remove</code></p>
<pre><code class="language-python">#***************   delete   ***************
myset.delete_one({"name":"杨幂"})
myset.delete_many({"king_name":None}) # 删除没有king_name域
myset.remove({"King":"菜虚鲲"},multi=False)
</code></pre>
<h5 id="134复合操作">1.3.4复合操作</h5>
<p><code>find_one_and_delete()</code></p>
<pre><code class="language-python">myset.find_one_and_delete({"King":"张一山"})
</code></pre>
<h5 id="135-索引操作">1.3.5 索引操作</h5>
<p><code>vreate_index(index)</code></p>
<p>功能:创建索引</p>
<p>参数:{name:1} --&gt; [('name'),1] kwargs为索引选项</p>
<p>返回值:索引名称</p>
<pre><code class="language-python">index1 = myset.create_index("name")
index2 = myset.create_index([("name",-1)],name="NAME")
print("1", index1)
print("2", index2)
</code></pre>
<p><code>list_indees()</code></p>
<p>dro_index()</p>
<p>drop_indexes</p>
<pre><code class="language-python">myset.drop_index("NAME")
myset.drop_index([('name',1)])
myset.drop_indexes()
</code></pre>
<h5 id="136-聚合操作">1.3.6 聚合操作</h5>
<p><code>aggregate([{},{},...])</code></p>
<p>功能:完成聚合操作</p>
<p>参数:聚合管道,同MongoDB shell</p>
<p>返回值:数据结果游标</p>
<pre><code class="language-python">myset = db.class0
pipe = [{"$match":{"gender":{"$exists":True}}},
      {"$sort":{"age":1}},
      {"$project":{"_id":0}}
      ]

cursor = myset.aggregate(pipe)

for i in cursor:
    print()
</code></pre>
<h5 id="137-文件存储">1.3.7 文件存储</h5>
<p><code>import bson</code></p>
<ol>
<li>
<p>将文件内容转换为bson二进制格式存储</p>
<p><code>content = bson.binary.Binary(bytes)</code></p>
<p>功能:将python字节串转换为bson</p>
<p>参数:要转换的字符串</p>
<p>返回值:bson</p>
<pre><code class="language-python">##################存储图片##################
from pymongo import MongoClient
import bson.binary

conn = MongoClient('127.0.0.1',27017)
db = conn.images
myset = db.girl


with open("./demo.jpg","rb") as f:
    data = f.read()

# 将data转换为bson
content = bson.binary.Binary(data)

# 插入到集合
dic = {"filename":"girl.jpg",'data':content}
myset.insert_one(dic)
f.close()
conn.close()
</code></pre>
<pre><code class="language-python">##################提取图片##################
from pymongo import MongoClient
import bson.binary

conn = MongoClient('127.0.0.1',27017)
db = conn.image
myset = db.girl

# 提取文件
img = myset.find_one({"filename":"demo.jpg"})

with open('mm.jpg','wb') as f :
    f.write(img['data'])

conn.close()
</code></pre>
</li>
</ol>
<h4 id="14-关闭连接">1.4 关闭连接</h4>
<pre><code class="language-python">conn.clse()
</code></pre><br><br>
来源:https://www.cnblogs.com/chancey/p/11305114.html
頁: [1]
查看完整版本: MongoDB