http://coligo.io/create-url-shortener-with-node-express-mongo/
https://github.com/coligo-io/url-shortener-node-mongo-express
let's go ahead and create the counters collection with a counter called url_countstarting at 0:
db.counters.insert({ _id: 'url_count', seq: 1 })
NodeJS has a great package for connecting to a MongoDB called mongoose which is a very intuitive ODM (Object Data Modeling) library.
https://github.com/coligo-io/url-shortener-node-mongo-express
brew update
brew install mongodb
mongodlet's go ahead and create the counters collection with a counter called url_countstarting at 0:
db.counters.insert({ _id: 'url_count', seq: 1 })
NodeJS has a great package for connecting to a MongoDB called mongoose which is a very intuitive ODM (Object Data Modeling) library.
npm install mongoose --save
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
Next we need to define a schema for our collection and using that schema, we create our model. The counters collection is rather straightforward:
// create the counters schema with an _id field and a seq field
var CounterSchema = Schema({
_id: {type: String, required: true},
seq: { type: Number, default: 0 }
});
// create a model from that schema
var counter = mongoose.model('counter', CounterSchema);
We'll do the same thing for our urls collection by defining it's schema as we did for the counters collection:
// create a schema for our links
var urlSchema = new Schema({
_id: {type: Number, index: true},
long_url: String,
created_at: Date
});
Before saving an entry in the urls collection, increment the global url_count in the counters collection and use that as the _id field of the urls collection
// The pre('save', callback) middleware executes the callback function
// every time before an entry is saved to the urls collection.
urlSchema.pre('save', function(next){
var doc = this;
// find the url_count and increment it by 1
counter.findByIdAndUpdate({_id: 'url_count'}, {$inc: {seq: 1} }, function(error, counter) {
if (error)
return next(error);
// set the _id of the urls collection to the incremented value of the counter
doc._id = counter.seq;
doc.created_at = new Date();
next();
});
});app.post('/api/shorten', function(req, res){
var longUrl = req.body.url;
var shortUrl = '';
// check if url already exists in database
Url.findOne({long_url: longUrl}, function (err, doc){
if (doc){
// base58 encode the unique _id of that document and construct the short URL
shortUrl = config.webhost + base58.encode(doc._id);
// since the document exists, we return it without creating a new entry
res.send({'shortUrl': shortUrl});
} else {
// The long URL was not found in the long_url field in our urls
// collection, so we need to create a new entry:
var newUrl = Url({
long_url: longUrl
});
// save the new link
newUrl.save(function(err) {
if (err){
console.log(err);
}
// construct the short URL
shortUrl = config.webhost + base58.encode(newUrl._id);
res.send({'shortUrl': shortUrl});
});
}
});
});
app.get('/:encoded_id', function(req, res){
var base58Id = req.params.encoded_id;
var id = base58.decode(base58Id);
// check if url already exists in database
Url.findOne({_id: id}, function (err, doc){
if (doc) {
// found an entry in the DB, redirect the user to their destination
res.redirect(doc.long_url);
} else {
// nothing found, take 'em home
res.redirect(config.webhost);
}
});
});