使用 Mean–Multer–Mongoose–Angular 更新或添加标签到图像

Posted

技术标签:

【中文标题】使用 Mean–Multer–Mongoose–Angular 更新或添加标签到图像【英文标题】:Updating or adding tags to images with Mean–Multer–Mongoose–Angular 【发布时间】:2017-08-02 12:52:21 【问题描述】:

我想尝试创建一个图像数据库,我也可以在其中标记图片。我使用了this example here 并想修改一些东西。对 Angular 和 mongDB 来说是全新的

这是我的猫鼬模型。

var UploadSchema = mongoose.Schema(
    name: String,
    tags: 
        ImageObjects: String,
        CreatorArtist: String,
        Question1: String,
        Question2: String
    ,
    created: Date,
    file: Object
);

我已经可以在本地提交/上传图像时添加一些标签并将标签存储在我的 MongoDB 中。

但现在我希望能够 .put() 如果需要的话再添加一些标签。 所以我像这样路由它

上传.js

var express = require('express');
var router = express.Router();
var fs = require('fs');
var Upload = require('../models/upload');
var multer = require('multer');
var upload = multer(
    dest: 'uploads/'
);
var _ = require('underscore');


/**
 * Create's the file in the database
 */
router.post('/', upload.single('file'), function(req, res, next) 
    var newUpload = 
        name: req.body.name,
        tags: req.body.tags,
        created: Date.now(),
        file: req.file

    ;
    Upload.create(newUpload, function(err, next) 
        if (err) 
            next(err);
         else 
            res.send(newUpload);
        
    );

);



/**
 * Gets the list of all files from the database
 */
router.get('/', function(req, res, next) 
    Upload.find(, function(err, uploads) 
        if (err) next(err);
        else 
            res.send(uploads);
        
    );
);


/**
* Change tags of one images. Maybe add some too
*/
router.put('/:uuid/:filename', function(req, res) 
    Upload.findOne(
        'file.filename': req.params.uuid,
        'file.originalname': req.params.filename
    , function(err, upload) 
        if (err) next(err);
        else 
            res.set(
                "Content-Disposition": 'inline; filename="' + upload.file.originalname + '"',
                "Content-Type": upload.file.mimetype
            );
            Upload = _.extend(Uploads, req.params);


            Upload.save(function (err)
              res.send(uploads);
            )
        
    );
);


/**
 * Gets a file from the hard drive based on the unique ID and the filename
 */

router.get('/:uuid/:filename', function(req, res, next) 
    //console.log(req.params);
    Upload.findOne(
        'file.filename': req.params.uuid,
        'file.originalname': req.params.filename
    , function(err, upload) 
        if (err) next(err);
        else 
            res.set(
                "Content-Disposition": 'inline; filename="' + upload.file.originalname + '"',
                "Content-Type": upload.file.mimetype
            );
            fs.createReadStream(upload.file.path).pipe(res);
        
    );
);

module.exports = router;

我认为这部分也是相关的,我从组成的 fileuploadExample.js 中更改了它 我只是将“post”更改为“put”。

var app = angular.module('fileUpload', ['ngFileUpload']);
var tempFileName, tempID;

app.controller('formCtrl', ['$http', 'Upload', '$scope', function($http, Upload, $scope) 

    $http.get('/uploads').then(function(response) 
        console.log(response.data);
        $scope.uploads = response.data;
    );

    $scope.submit = function() 
        Upload.upload(
            url: '/uploads',
            method: 'put',
            data: $scope.upload
        ).then(function(response) 
            tempID = response.data.file.filename;
            sessionStorage.setItem("tempID", tempID);

            tempFileName = response.data.file.originalname;
            sessionStorage.setItem("tempFileName", tempFileName);

            console.log(tempID);
            console.log(tempFileName);

            console.log(response.data);
            $scope.uploads.push(response.data);
            $scope.upload = ;
        )
    
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

这是 html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Test Tagging Example </title>
    <link rel="stylesheet" href="/css/normalize.css">
    <link rel="stylesheet" href="css/main.css">
    <link rel="stylesheet" href="css/jquery.steps.css">

    <script src="/vendor/angular.min.js"></script>
    <script src="/vendor/ng-file-upload-all.min.js"></script>
    <script src="/javascripts/fileTagging.js"></script>
    <script type="text/javascript" src="/vendor/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="/vendor/jquery.steps.js"></script>
    <script type="text/javascript" src="/vendor/jquery-validate.js"></script>
</head>

<body ng-app="fileUpload">

    <div ng-controller="formCtrl">
      <div>
          <img ng-src="" id="imageBox" />
          <script>

          var tempID = sessionStorage.getItem("tempID");
          var tempFileName = sessionStorage.getItem("tempFileName");
          console.log(tempID);
          console.log(tempFileName);


              document.getElementById('imageBox').src = "uploads/" + tempID + "/" + tempFileName;
          </script>
      </div>
        <!-- <div id="wizard"> -->
          <h2>Session tagging</h2>
          <!-- <section> -->
            <h1>Test Session</h1>
            <form ng-submit="submit()">
                <label for="q1">Question1:</label>
                <input type="text" name="q1" id="q1" ng-model="upload.tags.Question1" required/>
                <br/>
                <input type="submit" value="Submit" />
            </form>

            <a href="viewAll">View All</a>
            <a href="viewSingleUploaded">View Uploaded</a>
    </div>

</body>

</html>

那么我如何使用 .put() 更新/添加标签到带有现有标签的上传图像?如果需要,我会提供更多信息。

如果需要完整版可以下载here

【问题讨论】:

【参考方案1】:

嘿,我是原始示例的作者。我很高兴它帮助您入门!来自Mongoose docs 的推荐并使用model.findOneAndUpdate method。以下是基于您的模型的示例:

router.put('/:uuid/:filename', function(req, res) 
    Upload.findOneAndUpdate(
        'file.filename': req.params.uuid,
        'file.originalname': req.params.filename
    ,  $set:  tags: req.body.tags , 
    function(err, upload) 
        if (err) next(err);
        else 
          res.send(upload);
        
    );
);

希望对你有帮助!

编辑:

我还注意到您想添加“更多”标签。我的猜测是,您实际上想要猫鼬模型中的一组标签,而不是单个子对象。有两种方法可以实现:

1) 创建一个简单的数组:

var UploadSchema = mongoose.Schema(
    name: String,
    tags: [Array],
    created: Date,
    file: Object
);

2) 还是推荐的做法,创建子文档:

var TagSchema = mongoose.Schema(
    ImageObjects: String,
    CreatorArtist: String,
    Question1: String,
    Question2: String
);

var UploadSchema = mongoose.Schema(
    name: String,
    tags: [TagSchema],
    created: Date,
    file: Object
);

Here 是关于子文档的更多信息。根据文档,您可以得出以下结论:

router.put('/:uuid/:filename', function(req, res) 
    Upload.findOneAndUpdate(
        'file.filename': req.params.uuid,
        'file.originalname': req.params.filename
    ,  $push:  tags: req.body.tags  , 
    function(err, upload) 
        if (err) next(err);
        else 
          res.send(upload);
        
    );
);

【讨论】:

以上是关于使用 Mean–Multer–Mongoose–Angular 更新或添加标签到图像的主要内容,如果未能解决你的问题,请参考以下文章

将 Mongoose/Multer 文件上传的工作模态/FORM 更改为 MULTIPART/FORM - 模态保持打开状态

如何使用multer上传文件/在表格数据中发帖?

Multer模块将无法启动

MEAN - mongoose 使用 findById 获取完整对象

Mongoose 的默认 Promise 库在 MEAN 堆栈中已弃用

使用 mongoose 保存子文档数组会创建空数组 MEAN 堆栈