Almost done ! What’s missing is to save the images in the database and to create express endpoints to recover the images, and the images paginated by tags.
Part 4: MongodDb
To facilitate our queries to the database, we will use an ODM (Object Document Mapper), so, yes, the term can be scary but in fact it is made to make our life easier, it’s called Mongoose.
We will create a folder db to separate from the rest of the code and in db create a model folder, which symbolizes the format of objects existing in the database:
$ mkdir -p db/models
Install Mongoose:
$ npm install --save mongoose
First, create the model :
//content of db/models/image.js
const mongoose = require('mongoose');
// build the schema
const imageSchema = mongoose.Schema({
path: String,
tags: [String]
});
// compile the schema into a model
const Image = mongoose.model('Image', imageSchema);
module.exports = Image
Then the connection to the database:
//content of db/index.js
const mongoose = require('mongoose');
const Image = require('./models/image');
// connect the database
mongoose.connect('mongodb://localhost/images');
module.exports = Image
And finally, the persistence of the data in the api / app.js as well as the routes that will allow us to recover our images:
//content of api/app.js
const express = require('express')
const multer = require('multer')
const clarifay = require('./clarifay')
const fs = require('fs');
const Image = require('../db')
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads')
},
filename: (req, file, cb) => {
cb(null, `${Date.now()}.${file.mimetype.split('/')[1]}`)
}
})
const upload = multer({ storage })
const app = express()
app.post('/photos/upload', upload.array('photos'), (req, res, next) => {
const message = { "data": [] }
req.files.forEach(image => {
fs.readFile(image.path, function (err, data) {
// predict the contents of an image by passing in base 64 encoded file
clarifay
.analyse(new Buffer(data).toString('base64'))
.then(
response => {
const imageObject = {
'path': image.path,
'tags': serialize(response.outputs[0].data.concepts)
}
message.data.push(imageObject)
// save in db
const imageData = new Image(imageObject)
imageData.save()
// if every image has been proccessed send back the response
if (message.data.length == req.files.length) {
res.status(200).send(message)
}
},
err => console.error(err)
);
});
})
})
// get all images
app.get('/photos', (req, res, next) => {
Image.find({}, (err, images) => res.send(images))
})
// get images by tags
app.get('/photos/:tag', (req, res, next) => {
Image.find({ tags: req.params.tag }, (err, images) => res.send(images))
})
// get the tags from the Clarifay API
const serialize = (array) => {
let subjects = [];
array.forEach(function (element) {
subjects.push(element.name)
});
// get only the best of 3 results
return subjects.slice(0, 3)
}
module.exports = app
It’s done for this series !! You will find the complete code here