GO学习-(26) Go语言操作mongoDB
<h1 class="post-title">Go语言操作mongoDB</h1><p> </p>
<div class="cnblogs_code"><img src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" id="code_img_closed_a321bcbe-e526-4570-906f-8a22c356ce69" class="code_img_closed"><img src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" id="code_img_opened_a321bcbe-e526-4570-906f-8a22c356ce69" class="code_img_opened" style="display: none">
<div id="cnblogs_code_open_a321bcbe-e526-4570-906f-8a22c356ce69" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">package main
import (
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">context</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">fmt</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">log</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">time</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">go.mongodb.org/mongo-driver/bson</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">go.mongodb.org/mongo-driver/mongo</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">go.mongodb.org/mongo-driver/mongo/options</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
)
func ConnectToDB(uri, name </span><span style="color: rgba(0, 0, 255, 1)">string</span>, timeout time.Duration, num uint64) (*<span style="color: rgba(0, 0, 0, 1)">mongo.Database, error) {
ctx, cancel :</span>=<span style="color: rgba(0, 0, 0, 1)"> context.WithTimeout(context.Background(), timeout)
defer cancel()
o :</span>=<span style="color: rgba(0, 0, 0, 1)"> options.Client().ApplyURI(uri)
o.SetMaxPoolSize(num)
client, err :</span>=<span style="color: rgba(0, 0, 0, 1)"> mongo.Connect(ctx, o)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> nil, err
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> client.Database(name), nil
}
func main(){
mgClient, err :</span>= ConnectToDB(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">mongodb://192.168.10.10:27017</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">bigdata</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 128, 1)">10</span>, <span style="color: rgba(128, 0, 128, 1)">100</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">fmt.Println("链接失败")</span>
<span style="color: rgba(0, 0, 0, 1)"> log.Print(err)
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 指定获取要操作的数据集</span>
collection := mgClient.Collection(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">bigdata</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">fmt.Println(collection)</span>
<span style="color: rgba(0, 0, 0, 1)">
type Student </span><span style="color: rgba(0, 0, 255, 1)">struct</span><span style="color: rgba(0, 0, 0, 1)"> {
Name </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">
Age </span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">接下来,创建一些Student类型的值,准备插入到数据库中:</span>
s1 := Student{<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">小红</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 128, 1)">12</span><span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">插入文档
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">使用collection.InsertOne()方法插入一条文档记录:</span>
insertResult, err :=<span style="color: rgba(0, 0, 0, 1)"> collection.InsertOne(context.TODO(), s1)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
log.Print(err)
}
fmt.Println(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Inserted a single document: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, insertResult.InsertedID)
log.Println(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Inserted a single document: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, insertResult.InsertedID)
s2 :</span>= Student{<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">小兰</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">}
s3 :</span>= Student{<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">小黄</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 128, 1)">11</span><span style="color: rgba(0, 0, 0, 1)">}
students :</span>= []<span style="color: rgba(0, 0, 255, 1)">interface</span><span style="color: rgba(0, 0, 0, 1)">{}{s2, s3}
insertManyResult, err :</span>=<span style="color: rgba(0, 0, 0, 1)"> collection.InsertMany(context.TODO(), students)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
log.Print(err)
}
fmt.Println(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Inserted multiple documents: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, insertManyResult.InsertedIDs)
log.Println(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Inserted multiple documents: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, insertManyResult.InsertedIDs)
filter :</span>= bson.D{{<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">小兰</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">}}
update :</span>=<span style="color: rgba(0, 0, 0, 1)"> bson.D{
{</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">$inc</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, bson.D{
{</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">age</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">},
}},
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">接下来,就可以通过下面的语句找到小兰,给他增加一岁了:</span>
<span style="color: rgba(0, 0, 0, 1)">
updateResult, err :</span>=<span style="color: rgba(0, 0, 0, 1)"> collection.UpdateOne(context.TODO(), filter, update)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
log.Print(err)
}
fmt.Printf(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Matched %v documents and updated %v documents.\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, updateResult.MatchedCount, updateResult.ModifiedCount)
log.Printf(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Matched %v documents and updated %v documents.\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, updateResult.MatchedCount, updateResult.ModifiedCount)
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)"> result Student
err </span>= collection.FindOne(context.TODO(), filter).Decode(&<span style="color: rgba(0, 0, 0, 1)">result)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
log.Fatal(err)
}
fmt.Printf(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Found a single document: %+v\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, result)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 查询多个
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 将选项传递给Find()</span>
findOptions :=<span style="color: rgba(0, 0, 0, 1)"> options.Find()
findOptions.SetLimit(</span><span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 定义一个切片用来存储查询结果</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> results []*<span style="color: rgba(0, 0, 0, 1)">Student
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 把bson.D{{}}作为一个filter来匹配所有文档</span>
cur, err :=<span style="color: rgba(0, 0, 0, 1)"> collection.Find(context.TODO(), filter, findOptions)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
log.Fatal(err)
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 查找多个文档返回一个光标
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 遍历游标允许我们一次解码一个文档</span>
<span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> cur.Next(context.TODO()) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个值,将单个文档解码为该值</span>
<span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)"> elem Student
err :</span>= cur.Decode(&<span style="color: rgba(0, 0, 0, 1)">elem)
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
log.Fatal(err)
}
results </span>= append(results, &<span style="color: rgba(0, 0, 0, 1)">elem)
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err := cur.Err(); err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
log.Fatal(err)
}
fmt.Printf(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Found all document: %+v\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, results)
</span><span style="color: rgba(0, 0, 255, 1)">for</span> k, v :=<span style="color: rgba(0, 0, 0, 1)"> range results{
fmt.Printf(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">key:%v value:%v value type:%T\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, k, v, v)
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 删除名字是小黄的那个</span>
deleteResult1, err := collection.DeleteOne(context.TODO(), bson.D{{<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">小黄</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">}})
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
log.Fatal(err)
}
fmt.Printf(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Deleted %v documents in the trainers collection\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, deleteResult1.DeletedCount)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 删除所有</span>
deleteResult2, err :=<span style="color: rgba(0, 0, 0, 1)"> collection.DeleteMany(context.TODO(), bson.D{{}})
</span><span style="color: rgba(0, 0, 255, 1)">if</span> err !=<span style="color: rgba(0, 0, 0, 1)"> nil {
log.Fatal(err)
}
fmt.Printf(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Deleted %v documents in the trainers collection\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, deleteResult2.DeletedCount)
}</span></pre>
</div>
<span class="cnblogs_code_collapse">例子</span></div>
<p> </p>
<div class="post-content">
<p>mongoDB是目前比较流行的一个基于分布式文件存储的数据库,它是一个介于关系数据库和非关系数据库(NoSQL)之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。</p>
<h2 id="autoid-0-0-0">mongoDB介绍</h2>
<p>mongoDB是目前比较流行的一个基于分布式文件存储的数据库,它是一个介于关系数据库和非关系数据库(NoSQL)之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。</p>
<p>mongoDB中将一条数据存储为一个文档(document),数据结构由键值(key-value)对组成。 其中文档类似于我们平常编程中用到的JSON对象。 文档中的字段值可以包含其他文档,数组及文档数组。</p>
<h3 id="autoid-0-1-0">mongoDB相关概念</h3>
<p>mongoDB中相关概念与我们熟悉的SQL概念对比如下:</p>
<table>
<thead>
<tr><th>MongoDB术语/概念</th><th>说明</th><th>对比SQL术语/概念</th></tr>
</thead>
<tbody>
<tr>
<td>database</td>
<td>数据库</td>
<td>database</td>
</tr>
<tr>
<td>collection</td>
<td>集合</td>
<td>table</td>
</tr>
<tr>
<td>document</td>
<td>文档</td>
<td>row</td>
</tr>
<tr>
<td>field</td>
<td>字段</td>
<td>column</td>
</tr>
<tr>
<td>index</td>
<td>index</td>
<td>索引</td>
</tr>
<tr>
<td>primary key</td>
<td>主键 MongoDB自动将_id字段设置为主键</td>
<td>primary key</td>
</tr>
</tbody>
</table>
<h2 id="autoid-0-1-1">mongoDB安装</h2>
<p>我们这里下载和安装社区版,官网下载地址。 打开上述连接后,选择对应的版本、操作系统平台(常见的平台均支持)和包类型,点击Download按钮下载即可。</p>
<p>这里补充说明下,Windows平台有<code>ZIP</code>和<code>MSI</code>两种包类型: * ZIP:压缩文件版本 * MSI:可执行文件版本,点击”下一步”安装即可。</p>
<p>macOS平台除了在该网页下载<code>TGZ</code>文件外,还可以使用<code>Homebrew</code>安装。</p>
<p>更多安装细节可以参考官方安装教程,里面有<code>Linux</code>、<code>macOS</code>和<code>Windows</code>三大主流平台的安装教程。</p>
<h2 id="autoid-0-2-0">mongoDB基本使用</h2>
<h3 id="autoid-0-3-0">启动mongoDB数据库</h3>
<h4 id="windows">Windows</h4>
<pre class="line-numbers language-bash"><code class=" language-bash"><span class="token string">"C:\Program Files\MongoDB\Server\4.2\bin\mongod.exe"</span> --dbpath<span class="token operator">=</span><span class="token string">"c:\data\db"</span>
</code></pre>
<h4 id="mac">Mac</h4>
<pre class="line-numbers language-bash"><code class=" language-bash">mongod --config /usr/local/etc/mongod.conf
</code></pre>
<p>或</p>
<pre class="line-numbers language-bash"><code class=" language-bash">brew services start mongodb-community@4.2
</code></pre>
<h3 id="autoid-0-3-1">启动client</h3>
<h4 id="windows-1">Windows</h4>
<pre class="line-numbers language-bash"><code class=" language-bash"><span class="token string">"C:\Program Files\MongoDB\Server\4.2\bin\mongo.exe"</span>
</code></pre>
<h4 id="mac-1">Mac</h4>
<pre class="line-numbers language-bash"><code class=" language-bash">mongo
</code></pre>
<h3 id="autoid-0-3-2">数据库常用命令</h3>
<p><code>show dbs;</code>:查看数据库</p>
<pre class="line-numbers language-bash"><code class=" language-bash"><span class="token operator">></span> show dbs<span class="token punctuation">;</span>
admin 0.000GB
config0.000GB
local 0.000GB
<span class="token function">test</span> 0.000GB
</code></pre>
<p><code>use q1mi;</code>:切换到指定数据库,如果不存在该数据库就创建。</p>
<pre class="line-numbers language-bash"><code class=" language-bash"><span class="token operator">></span> use q1mi<span class="token punctuation">;</span>
switched to db q1mi
</code></pre>
<p><code>db;</code>:显示当前所在数据库。</p>
<pre class="line-numbers language-bash"><code class=" language-bash"><span class="token operator">></span> db<span class="token punctuation">;</span>
q1mi
</code></pre>
<p><code>db.dropDatabase()</code>:删除当前数据库</p>
<pre class="line-numbers language-bash"><code class=" language-bash"><span class="token operator">></span> db.dropDatabase<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{</span> <span class="token string">"ok"</span> <span class="token keyword keyword-:">:</span> 1 <span class="token punctuation">}</span>
</code></pre>
<h3 id="autoid-0-3-3">数据集常用命令</h3>
<p><code>db.createCollection(name,options)</code>:创建数据集</p>
<ul>
<li>name:数据集名称</li>
<li>options:可选参数,指定内存大小和索引。</li>
</ul>
<pre class="line-numbers language-bash"><code class=" language-bash"><span class="token operator">></span> db.createCollection<span class="token punctuation">(</span><span class="token string">"student"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{</span> <span class="token string">"ok"</span> <span class="token keyword keyword-:">:</span> 1 <span class="token punctuation">}</span>
</code></pre>
<p><code>show collections;</code>:查看当前数据库中所有集合。</p>
<pre class="line-numbers language-bash"><code class=" language-bash"><span class="token operator">></span> show collections<span class="token punctuation">;</span>
student
</code></pre>
<p><code>db.student.drop()</code>:删除指定数据集</p>
<pre class="line-numbers language-bash"><code class=" language-bash"><span class="token operator">></span> db.student.drop<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token boolean">true</span>
</code></pre>
<h3 id="autoid-0-3-4">文档常用命令</h3>
<p>插入一条文档:</p>
<pre class="line-numbers language-bash"><code class=" language-bash"><span class="token operator">></span> db.student.insertOne<span class="token punctuation">(</span><span class="token punctuation">{</span>name:<span class="token string">"小王子"</span>,age:18<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{</span>
<span class="token string">"acknowledged"</span> <span class="token keyword keyword-:">:</span> true,
<span class="token string">"insertedId"</span> <span class="token keyword keyword-:">:</span> ObjectId<span class="token punctuation">(</span><span class="token string">"5db149e904b33457f8c02509"</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<p>插入多条文档:</p>
<pre class="line-numbers language-bash"><code class=" language-bash"><span class="token operator">></span> db.student.insertMany<span class="token punctuation">(</span><span class="token punctuation">[</span>
<span class="token punctuation">..</span>. <span class="token punctuation">{</span>name:<span class="token string">"张三"</span>,age:20<span class="token punctuation">}</span>,
<span class="token punctuation">..</span>. <span class="token punctuation">{</span>name:<span class="token string">"李四"</span>,age:25<span class="token punctuation">}</span>
<span class="token punctuation">..</span>. <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{</span>
<span class="token string">"acknowledged"</span> <span class="token keyword keyword-:">:</span> true,
<span class="token string">"insertedIds"</span> <span class="token keyword keyword-:">:</span> <span class="token punctuation">[</span>
ObjectId<span class="token punctuation">(</span><span class="token string">"5db14c4704b33457f8c0250a"</span><span class="token punctuation">)</span>,
ObjectId<span class="token punctuation">(</span><span class="token string">"5db14c4704b33457f8c0250b"</span><span class="token punctuation">)</span>
<span class="token punctuation">]</span>
<span class="token punctuation">}</span>
</code></pre>
<p>查询所有文档:</p>
<pre class="line-numbers language-bash"><code class=" language-bash"><span class="token operator">></span> db.student.find<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{</span> <span class="token string">"_id"</span> <span class="token keyword keyword-:">:</span> ObjectId<span class="token punctuation">(</span><span class="token string">"5db149e904b33457f8c02509"</span><span class="token punctuation">)</span>, <span class="token string">"name"</span> <span class="token keyword keyword-:">:</span> <span class="token string">"小王子"</span>, <span class="token string">"age"</span> <span class="token keyword keyword-:">:</span> 18 <span class="token punctuation">}</span>
<span class="token punctuation">{</span> <span class="token string">"_id"</span> <span class="token keyword keyword-:">:</span> ObjectId<span class="token punctuation">(</span><span class="token string">"5db14c4704b33457f8c0250a"</span><span class="token punctuation">)</span>, <span class="token string">"name"</span> <span class="token keyword keyword-:">:</span> <span class="token string">"张三"</span>, <span class="token string">"age"</span> <span class="token keyword keyword-:">:</span> 20 <span class="token punctuation">}</span>
<span class="token punctuation">{</span> <span class="token string">"_id"</span> <span class="token keyword keyword-:">:</span> ObjectId<span class="token punctuation">(</span><span class="token string">"5db14c4704b33457f8c0250b"</span><span class="token punctuation">)</span>, <span class="token string">"name"</span> <span class="token keyword keyword-:">:</span> <span class="token string">"李四"</span>, <span class="token string">"age"</span> <span class="token keyword keyword-:">:</span> 25 <span class="token punctuation">}</span>
</code></pre>
<p>查询age>20岁的文档:</p>
<pre class="line-numbers language-bash"><code class=" language-bash"><span class="token operator">></span> db.student.find<span class="token punctuation">(</span>
<span class="token punctuation">..</span>. <span class="token punctuation">{</span>age:<span class="token punctuation">{</span><span class="token variable">$gt</span>:20<span class="token punctuation">}</span><span class="token punctuation">}</span>
<span class="token punctuation">..</span>. <span class="token punctuation">)</span>
<span class="token punctuation">{</span> <span class="token string">"_id"</span> <span class="token keyword keyword-:">:</span> ObjectId<span class="token punctuation">(</span><span class="token string">"5db14c4704b33457f8c0250b"</span><span class="token punctuation">)</span>, <span class="token string">"name"</span> <span class="token keyword keyword-:">:</span> <span class="token string">"李四"</span>, <span class="token string">"age"</span> <span class="token keyword keyword-:">:</span> 25 <span class="token punctuation">}</span>
</code></pre>
<p>更新文档:</p>
<pre class="line-numbers language-bash"><code class=" language-bash"><span class="token operator">></span> db.student.update<span class="token punctuation">(</span>
<span class="token punctuation">..</span>. <span class="token punctuation">{</span>name:<span class="token string">"小王子"</span><span class="token punctuation">}</span>,
<span class="token punctuation">..</span>. <span class="token punctuation">{</span>name:<span class="token string">"老王子"</span>,age:98<span class="token punctuation">}</span>
<span class="token punctuation">..</span>. <span class="token punctuation">)</span><span class="token punctuation">;</span>
WriteResult<span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token string">"nMatched"</span> <span class="token keyword keyword-:">:</span> 1, <span class="token string">"nUpserted"</span> <span class="token keyword keyword-:">:</span> 0, <span class="token string">"nModified"</span> <span class="token keyword keyword-:">:</span> 1 <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token operator">></span> db.student.find<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span> <span class="token string">"_id"</span> <span class="token keyword keyword-:">:</span> ObjectId<span class="token punctuation">(</span><span class="token string">"5db149e904b33457f8c02509"</span><span class="token punctuation">)</span>, <span class="token string">"name"</span> <span class="token keyword keyword-:">:</span> <span class="token string">"老王子"</span>, <span class="token string">"age"</span> <span class="token keyword keyword-:">:</span> 98 <span class="token punctuation">}</span>
<span class="token punctuation">{</span> <span class="token string">"_id"</span> <span class="token keyword keyword-:">:</span> ObjectId<span class="token punctuation">(</span><span class="token string">"5db14c4704b33457f8c0250a"</span><span class="token punctuation">)</span>, <span class="token string">"name"</span> <span class="token keyword keyword-:">:</span> <span class="token string">"张三"</span>, <span class="token string">"age"</span> <span class="token keyword keyword-:">:</span> 20 <span class="token punctuation">}</span>
<span class="token punctuation">{</span> <span class="token string">"_id"</span> <span class="token keyword keyword-:">:</span> ObjectId<span class="token punctuation">(</span><span class="token string">"5db14c4704b33457f8c0250b"</span><span class="token punctuation">)</span>, <span class="token string">"name"</span> <span class="token keyword keyword-:">:</span> <span class="token string">"李四"</span>, <span class="token string">"age"</span> <span class="token keyword keyword-:">:</span> 25 <span class="token punctuation">}</span>
</code></pre>
<p>删除文档:</p>
<pre class="line-numbers language-bash"><code class=" language-bash"><span class="token operator">></span> db.student.deleteOne<span class="token punctuation">(</span><span class="token punctuation">{</span>name:<span class="token string">"李四"</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">{</span> <span class="token string">"acknowledged"</span> <span class="token keyword keyword-:">:</span> true, <span class="token string">"deletedCount"</span> <span class="token keyword keyword-:">:</span> 1 <span class="token punctuation">}</span>
<span class="token operator">></span> db.student.find<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span> <span class="token string">"_id"</span> <span class="token keyword keyword-:">:</span> ObjectId<span class="token punctuation">(</span><span class="token string">"5db149e904b33457f8c02509"</span><span class="token punctuation">)</span>, <span class="token string">"name"</span> <span class="token keyword keyword-:">:</span> <span class="token string">"老王子"</span>, <span class="token string">"age"</span> <span class="token keyword keyword-:">:</span> 98 <span class="token punctuation">}</span>
<span class="token punctuation">{</span> <span class="token string">"_id"</span> <span class="token keyword keyword-:">:</span> ObjectId<span class="token punctuation">(</span><span class="token string">"5db14c4704b33457f8c0250a"</span><span class="token punctuation">)</span>, <span class="token string">"name"</span> <span class="token keyword keyword-:">:</span> <span class="token string">"张三"</span>, <span class="token string">"age"</span> <span class="token keyword keyword-:">:</span> 20 <span class="token punctuation">}</span>
</code></pre>
<p>命令实在太多,更多命令请参阅官方文档:shell命令和官方文档:CRUD操作。</p>
<h2 id="autoid-0-3-5">Go语言操作mongoDB</h2>
<p>我们这里使用的是官方的驱动包,当然你也可以使用第三方的驱动包(如mgo等)。 mongoDB官方版的Go驱动发布的比较晚(2018年12月13号)。</p>
<h3 id="autoid-0-4-0">安装mongoDB Go驱动包</h3>
<pre class="line-numbers language-bash"><code class=" language-bash">go get github.com/mongodb/mongo-go-driver
</code></pre>
<h3 id="autoid-0-4-1">通过Go代码连接mongoDB</h3>
<pre class="line-numbers language-go"><code class=" language-go"><span class="token keyword keyword-package">package</span> main
<span class="token keyword keyword-import">import</span> <span class="token punctuation">(</span>
<span class="token string">"context"</span>
<span class="token string">"fmt"</span>
<span class="token string">"log"</span>
<span class="token string">"go.mongodb.org/mongo-driver/mongo"</span>
<span class="token string">"go.mongodb.org/mongo-driver/mongo/options"</span>
<span class="token punctuation">)</span>
<span class="token keyword keyword-func">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// 设置客户端连接配置</span>
clientOptions <span class="token operator">:=</span> options<span class="token punctuation">.</span><span class="token function">Client</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">ApplyURI</span><span class="token punctuation">(</span><span class="token string">"mongodb://localhost:27017"</span><span class="token punctuation">)</span>
<span class="token comment">// 连接到MongoDB</span>
client<span class="token punctuation">,</span> err <span class="token operator">:=</span> mongo<span class="token punctuation">.</span><span class="token function">Connect</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">TODO</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> clientOptions<span class="token punctuation">)</span>
<span class="token keyword keyword-if">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// 检查连接</span>
err <span class="token operator">=</span> client<span class="token punctuation">.</span><span class="token function">Ping</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">TODO</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">)</span>
<span class="token keyword keyword-if">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"Connected to MongoDB!"</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<p>连接上MongoDB之后,可以通过下面的语句处理我们上面的q1mi数据库中的student数据集了:</p>
<pre class="line-numbers language-go"><code class=" language-go"><span class="token comment">// 指定获取要操作的数据集</span>
collection <span class="token operator">:=</span> client<span class="token punctuation">.</span><span class="token function">Database</span><span class="token punctuation">(</span><span class="token string">"q1mi"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Collection</span><span class="token punctuation">(</span><span class="token string">"student"</span><span class="token punctuation">)</span>
</code></pre>
<p>处理完任务之后可以通过下面的命令断开与MongoDB的连接:</p>
<pre class="line-numbers language-go"><code class=" language-go"><span class="token comment">// 断开连接</span>
err <span class="token operator">=</span> client<span class="token punctuation">.</span><span class="token function">Disconnect</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">TODO</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token keyword keyword-if">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"Connection to MongoDB closed."</span><span class="token punctuation">)</span>
</code></pre>
<h3 id="autoid-0-4-2">连接池模式</h3>
<pre class="line-numbers language-go"><code class=" language-go"><span class="token keyword keyword-import">import</span> <span class="token punctuation">(</span>
<span class="token string">"context"</span>
<span class="token string">"time"</span>
<span class="token string">"go.mongodb.org/mongo-driver/mongo"</span>
<span class="token string">"go.mongodb.org/mongo-driver/mongo/options"</span>
<span class="token punctuation">)</span>
<span class="token keyword keyword-func">func</span> <span class="token function">ConnectToDB</span><span class="token punctuation">(</span>uri<span class="token punctuation">,</span> name <span class="token builtin">string</span><span class="token punctuation">,</span> timeout time<span class="token punctuation">.</span>Duration<span class="token punctuation">,</span> num <span class="token builtin">uint64</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token operator">*</span>mongo<span class="token punctuation">.</span>Database<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
ctx<span class="token punctuation">,</span> cancel <span class="token operator">:=</span> context<span class="token punctuation">.</span><span class="token function">WithTimeout</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">Background</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> timeout<span class="token punctuation">)</span>
<span class="token keyword keyword-defer">defer</span> <span class="token function">cancel</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
o <span class="token operator">:=</span> options<span class="token punctuation">.</span><span class="token function">Client</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">ApplyURI</span><span class="token punctuation">(</span>uri<span class="token punctuation">)</span>
o<span class="token punctuation">.</span><span class="token function">SetMaxPoolSize</span><span class="token punctuation">(</span>num<span class="token punctuation">)</span>
client<span class="token punctuation">,</span> err <span class="token operator">:=</span> mongo<span class="token punctuation">.</span><span class="token function">Connect</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> o<span class="token punctuation">)</span>
<span class="token keyword keyword-if">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword keyword-return">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> err
<span class="token punctuation">}</span>
<span class="token keyword keyword-return">return</span> client<span class="token punctuation">.</span><span class="token function">Database</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
</code></pre>
<h3 id="autoid-0-4-3">BSON</h3>
<p>MongoDB中的JSON文档存储在名为BSON(二进制编码的JSON)的二进制表示中。与其他将JSON数据存储为简单字符串和数字的数据库不同,BSON编码扩展了JSON表示,使其包含额外的类型,如int、long、date、浮点数和decimal128。这使得应用程序更容易可靠地处理、排序和比较数据。</p>
<p>连接MongoDB的Go驱动程序中有两大类型表示BSON数据:<code>D</code>和<code>Raw</code>。</p>
<p>类型<code>D</code>家族被用来简洁地构建使用本地Go类型的BSON对象。这对于构造传递给MongoDB的命令特别有用。<code>D</code>家族包括四类:</p>
<ul>
<li>D:一个BSON文档。这种类型应该在顺序重要的情况下使用,比如MongoDB命令。</li>
<li>M:一张无序的map。它和D是一样的,只是它不保持顺序。</li>
<li>A:一个BSON数组。</li>
<li>E:D里面的一个元素。</li>
</ul>
<p>要使用BSON,需要先导入下面的包:</p>
<pre class="line-numbers language-go"><code class=" language-go"><span class="token keyword keyword-import">import</span> <span class="token string">"go.mongodb.org/mongo-driver/bson"</span>
</code></pre>
<p>下面是一个使用D类型构建的过滤器文档的例子,它可以用来查找name字段与’张三’或’李四’匹配的文档:</p>
<pre class="line-numbers language-go"><code class=" language-go">bson<span class="token punctuation">.</span>D<span class="token punctuation">{</span><span class="token punctuation">{</span>
<span class="token string">"name"</span><span class="token punctuation">,</span>
bson<span class="token punctuation">.</span>D<span class="token punctuation">{</span><span class="token punctuation">{</span>
<span class="token string">"$in"</span><span class="token punctuation">,</span>
bson<span class="token punctuation">.</span>A<span class="token punctuation">{</span><span class="token string">"张三"</span><span class="token punctuation">,</span> <span class="token string">"李四"</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">}</span>
</code></pre>
<p><code>Raw</code>类型家族用于验证字节切片。你还可以使用<code>Lookup()</code>从原始类型检索单个元素。如果你不想要将BSON反序列化成另一种类型的开销,那么这是非常有用的。这个教程我们将只使用D类型。</p>
<h3 id="autoid-0-4-4">CRUD</h3>
<p>我们现在Go代码中定义一个<code>Studet</code>类型如下:</p>
<pre class="line-numbers language-go"><code class=" language-go"><span class="token keyword keyword-type">type</span> Student <span class="token keyword keyword-struct">struct</span> <span class="token punctuation">{</span>
Name <span class="token builtin">string</span>
Age <span class="token builtin">int</span>
<span class="token punctuation">}</span>
</code></pre>
<p>接下来,创建一些<code>Student</code>类型的值,准备插入到数据库中:</p>
<pre class="line-numbers language-go"><code class=" language-go">s1 <span class="token operator">:=</span> Student<span class="token punctuation">{</span><span class="token string">"小红"</span><span class="token punctuation">,</span> <span class="token number">12</span><span class="token punctuation">}</span>
s2 <span class="token operator">:=</span> Student<span class="token punctuation">{</span><span class="token string">"小兰"</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">}</span>
s3 <span class="token operator">:=</span> Student<span class="token punctuation">{</span><span class="token string">"小黄"</span><span class="token punctuation">,</span> <span class="token number">11</span><span class="token punctuation">}</span>
</code></pre>
<h4 id="插入文档">插入文档</h4>
<p>使用<code>collection.InsertOne()</code>方法插入一条文档记录:</p>
<pre class="line-numbers language-go"><code class=" language-go">insertResult<span class="token punctuation">,</span> err <span class="token operator">:=</span> collection<span class="token punctuation">.</span><span class="token function">InsertOne</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">TODO</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> s1<span class="token punctuation">)</span>
<span class="token keyword keyword-if">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"Inserted a single document: "</span><span class="token punctuation">,</span> insertResult<span class="token punctuation">.</span>InsertedID<span class="token punctuation">)</span>
</code></pre>
<p>使用<code>collection.InsertMany()</code>方法插入多条文档记录:</p>
<pre class="line-numbers language-go"><code class=" language-go">students <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token keyword keyword-interface">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">{</span>s2<span class="token punctuation">,</span> s3<span class="token punctuation">}</span>
insertManyResult<span class="token punctuation">,</span> err <span class="token operator">:=</span> collection<span class="token punctuation">.</span><span class="token function">InsertMany</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">TODO</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> students<span class="token punctuation">)</span>
<span class="token keyword keyword-if">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"Inserted multiple documents: "</span><span class="token punctuation">,</span> insertManyResult<span class="token punctuation">.</span>InsertedIDs<span class="token punctuation">)</span>
</code></pre>
<h4 id="更新文档">更新文档</h4>
<p><code>updateone()</code>方法允许你更新单个文档。它需要一个筛选器文档来匹配数据库中的文档,并需要一个更新文档来描述更新操作。你可以使用<code>bson.D</code>类型来构建筛选文档和更新文档:</p>
<pre class="line-numbers language-go"><code class=" language-go">filter <span class="token operator">:=</span> bson<span class="token punctuation">.</span>D<span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token string">"小兰"</span><span class="token punctuation">}</span><span class="token punctuation">}</span>
update <span class="token operator">:=</span> bson<span class="token punctuation">.</span>D<span class="token punctuation">{</span>
<span class="token punctuation">{</span><span class="token string">"$inc"</span><span class="token punctuation">,</span> bson<span class="token punctuation">.</span>D<span class="token punctuation">{</span>
<span class="token punctuation">{</span><span class="token string">"age"</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre>
<p>接下来,就可以通过下面的语句找到小兰,给他增加一岁了:</p>
<pre class="line-numbers language-go"><code class=" language-go">updateResult<span class="token punctuation">,</span> err <span class="token operator">:=</span> collection<span class="token punctuation">.</span><span class="token function">UpdateOne</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">TODO</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> filter<span class="token punctuation">,</span> update<span class="token punctuation">)</span>
<span class="token keyword keyword-if">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"Matched %v documents and updated %v documents.\n"</span><span class="token punctuation">,</span> updateResult<span class="token punctuation">.</span>MatchedCount<span class="token punctuation">,</span> updateResult<span class="token punctuation">.</span>ModifiedCount<span class="token punctuation">)</span>
</code></pre>
<h4 id="查找文档">查找文档</h4>
<p>要找到一个文档,你需要一个filter文档,以及一个指向可以将结果解码为其值的指针。要查找单个文档,使用<code>collection.FindOne()</code>。这个方法返回一个可以解码为值的结果。</p>
<p>我们使用上面定义过的那个filter来查找姓名为’小兰’的文档。</p>
<pre class="line-numbers language-go"><code class=" language-go"><span class="token comment">// 创建一个Student变量用来接收查询的结果</span>
<span class="token keyword keyword-var">var</span> result Student
err <span class="token operator">=</span> collection<span class="token punctuation">.</span><span class="token function">FindOne</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">TODO</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> filter<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Decode</span><span class="token punctuation">(</span><span class="token operator">&</span>result<span class="token punctuation">)</span>
<span class="token keyword keyword-if">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"Found a single document: %+v\n"</span><span class="token punctuation">,</span> result<span class="token punctuation">)</span>
</code></pre>
<p>要查找多个文档,请使用<code>collection.Find()</code>。此方法返回一个游标。游标提供了一个文档流,你可以通过它一次迭代和解码一个文档。当游标用完之后,应该关闭游标。下面的示例将使用<code>options</code>包设置一个限制以便只返回两个文档。</p>
<pre class="line-numbers language-go"><code class=" language-go"><span class="token comment">// 查询多个</span>
<span class="token comment">// 将选项传递给Find()</span>
findOptions <span class="token operator">:=</span> options<span class="token punctuation">.</span><span class="token function">Find</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
findOptions<span class="token punctuation">.</span><span class="token function">SetLimit</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span>
<span class="token comment">// 定义一个切片用来存储查询结果</span>
<span class="token keyword keyword-var">var</span> results <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">*</span>Student
<span class="token comment">// 把bson.D{{}}作为一个filter来匹配所有文档</span>
cur<span class="token punctuation">,</span> err <span class="token operator">:=</span> collection<span class="token punctuation">.</span><span class="token function">Find</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">TODO</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> bson<span class="token punctuation">.</span>D<span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">,</span> findOptions<span class="token punctuation">)</span>
<span class="token keyword keyword-if">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// 查找多个文档返回一个光标</span>
<span class="token comment">// 遍历游标允许我们一次解码一个文档</span>
<span class="token keyword keyword-for">for</span> cur<span class="token punctuation">.</span><span class="token function">Next</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">TODO</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// 创建一个值,将单个文档解码为该值</span>
<span class="token keyword keyword-var">var</span> elem Student
err <span class="token operator">:=</span> cur<span class="token punctuation">.</span><span class="token function">Decode</span><span class="token punctuation">(</span><span class="token operator">&</span>elem<span class="token punctuation">)</span>
<span class="token keyword keyword-if">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
results <span class="token operator">=</span> <span class="token function">append</span><span class="token punctuation">(</span>results<span class="token punctuation">,</span> <span class="token operator">&</span>elem<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword keyword-if">if</span> err <span class="token operator">:=</span> cur<span class="token punctuation">.</span><span class="token function">Err</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// 完成后关闭游标</span>
cur<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">TODO</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"Found multiple documents (array of pointers): %#v\n"</span><span class="token punctuation">,</span> results<span class="token punctuation">)</span>
</code></pre>
<h4 id="删除文档">删除文档</h4>
<p>最后,可以使用<code>collection.DeleteOne()</code>或<code>collection.DeleteMany()</code>删除文档。如果你传递<code>bson.D{{}}</code>作为过滤器参数,它将匹配数据集中的所有文档。还可以使用<code>collection. drop()</code>删除整个数据集。</p>
<pre class="line-numbers language-go"><code class=" language-go"><span class="token comment">// 删除名字是小黄的那个</span>
deleteResult1<span class="token punctuation">,</span> err <span class="token operator">:=</span> collection<span class="token punctuation">.</span><span class="token function">DeleteOne</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">TODO</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> bson<span class="token punctuation">.</span>D<span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token string">"name"</span><span class="token punctuation">,</span><span class="token string">"小黄"</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword keyword-if">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"Deleted %v documents in the trainers collection\n"</span><span class="token punctuation">,</span> deleteResult1<span class="token punctuation">.</span>DeletedCount<span class="token punctuation">)</span>
<span class="token comment">// 删除所有</span>
deleteResult2<span class="token punctuation">,</span> err <span class="token operator">:=</span> collection<span class="token punctuation">.</span><span class="token function">DeleteMany</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">TODO</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> bson<span class="token punctuation">.</span>D<span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword keyword-if">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"Deleted %v documents in the trainers collection\n"</span><span class="token punctuation">,</span> deleteResult2<span class="token punctuation">.</span>DeletedCount<span class="token punctuation">)</span>
</code></pre>
<p>更多方法请查阅官方文档。</p>
<h2 id="autoid-0-4-5">参考链接</h2>
<p>https://docs.mongodb.com/manual/mongo/</p>
<p>https://www.mongodb.com/blog/post/mongodb-go-driver-tutorial</p>
</div><br><br>
来源:https://www.cnblogs.com/xiao-xue-di/p/14419126.html
頁:
[1]