Skip to content
techird edited this page Apr 6, 2016 · 2 revisions

Step3. 把文件访问信息存储到 MongoDB 中

上一步:Step2. 把上传的图片存储到腾讯云 COS 服务中

本步骤完整源码在 workflow/step-3 分支上,提交记录为 a851124

到现在,我们已经可以成功让用户把文件上传到 COS 服务中,紧接着,我们需要把这部分访问信息存储到 MongoDB 上,方便后续为图片添加元数据,并且支持列表、搜索等功能。

腾讯云提供的 MongoDB 服务目前需要申请使用,如果读者还没有体验资格,可以点击这里申请一下。

申请审批之后,打开 MongoDB 控制台,会发现已经拥有一个默认集群。选中集群,点击上面的「修改密码」按钮,设置一下 MongoDB 的访问密码。

修改集群密码

可以使用官方的 mongodb 来访问腾讯云的 MongoDB 集群。

同样的,我们使用 npm 来安装一下 mongodb

npm install mongodb --save

安装之后,我们来创建 lib/mongo.js 封装一下 MongoDB 的连接方法。

// lib/mongo.js
'use strict';

const MongoClient = require('mongodb').MongoClient;

const user = 'rwuser';
const password = 'mypassword';
const endpoint = "10.66.125.158:27017";

const url = `mongodb://${user}:${password}@${endpoint}/?authMechanism=MONGODB-CR`;

/**
 * 连接到 mongodb
 * 
*/
function connect(callback) {
    return MongoClient.connect(url, callback);
}

exports.connect = connect;

其中,腾讯云 MongoDB 集群的用户名固定为 rwuser,密码就是刚才设置的密码,endpoint 可以在控制台的集群信息中得到。

下面,我们将使用这里的 connect() 方法连接到 MongoDB 集群,并且插入上一步收集到的文件信息。继续修改上传过程代码。

// handle/upload.js
const mongo = require("../lib/mongo");
function upload(request, response) {
    // ...(省略 uploadToServer 部分)
    
    function uploadToCos(file) {
        // upload file to cos
        
        cos.upload(..., (cosResult) => {
            // ...
            // 到目前文件已经上传到 COS,并且取得访问信息,下一步将其规范化,保存到 MongoDB 中
            
            // prepare file info, insert to mongodb later
            const fileInfo = {
                name: file.originalname,
                size: file.size,
                mime: file.mimetype,
                url: cosResult.data.access_url,
                cos: cosResult.data, // save all cos context
                meta: {}
            };
            
            saveToMongo(fileInfo);
        });
    }

    function saveToMongo(fileInfo) {
        // connect to mongodb
        mongo.connect((mongoError, db) => {
            if (mongoError) {
                print({ mongoError });
                db.close();
                return;
            }
            
            // insert fileInfo to the `image` connection 
            const collection = db.collection("images");
            collection.insertOne(fileInfo, (insertError, insertResult) => {
                if (insertError) {
                    print({ insertError });
                    db.close();
                    return;
                }
                console.log("#3. Saved to mongodb:");
                console.log(JSON.stringify({ insertResult, fileInfo }, null, 4));
                
                print({ fileInfo });
                db.close();
            });
        });
    }
}

这时候,用户上传图片之后,可以看到服务器输出:

服务器输出

同时,服务器日志里显示:

 #3. Saved to mongodb:
{
    "insertResult": {
        "ok": 1,
        "n": 1,
        "lastOp": "6270093661598384129",
        "electionId": "56fbd4fbfc071c79d8a9797e"
    },
    "fileInfo": {
        "name": "qq.png",
        "size": 59482,
        "mime": "image/png",
        "url": "http://image-10028115.file.myqcloud.com/uploads/0070468356c9dad63945ae5eca5e6914.png",
        "cos": {
            "access_url": "http://image-10028115.file.myqcloud.com/uploads/0070468356c9dad63945ae5eca5e6914.png",
            "resource_path": "/uploads/0070468356c9dad63945ae5eca5e6914.png",
            "source_url": "http://image-10028115.cos.myqcloud.com/uploads/0070468356c9dad63945ae5eca5e6914.png",
            "url": "http://web.file.myqcloud.com/files/v1/uploads/0070468356c9dad63945ae5eca5e6914.png"
        },
        "meta": {},
        "_id": "5703d8f7571756c73e7bca33"
    }
}

可以看到,数据已经成功插入到 MongoDB 中。

在使用 MongoDB 的时候,都是先连接得到 db 实例,然后再打开目标 collection,对 collection 进行操作。比如这里使用的是 collection.insertOne() 来插入数据。MongoDB 可以直接操作对象文档,非常适合用于元数据的存储。

关于 MongoDB 的使用方法,建议参考官方 API 文档

下一步:Step4. 列出所有上传的文件记录