From 0c6c170754e8dcfda58816acbb460d2222f73bc0 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Sun, 7 Jun 2015 17:15:53 -0700 Subject: [PATCH 1/3] initial script to flatten user object --- seed/flattenUser.js | 79 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 seed/flattenUser.js diff --git a/seed/flattenUser.js b/seed/flattenUser.js new file mode 100644 index 0000000000..a01ccfb420 --- /dev/null +++ b/seed/flattenUser.js @@ -0,0 +1,79 @@ +/* eslint-disable no-process-exit */ +require('dotenv').load(); +var assign = require('lodash/object/assign'), + Rx = require('rx'), + mongodb = require('mongodb'), + secrets = require('../config/secrets'); + +var MongoClient = mongodb.MongoClient; + +function createConnection(URI) { + return Rx.Observable.create(function(observer) { + MongoClient.connect(URI, function(err, database) { + if (err) { + return observer.onError(err); + } + observer.onNext(database); + }); + }); +} + +function createQuery(db, collection, selection, options, batchSize) { + return Rx.Observable.create(function (observer) { + console.log('Creating cursor...'); + var cursor = db.collection(collection).find(selection, options); + cursor.batchSize(batchSize || 20); + // Cursor.each will yield all doc from a batch in the same tick, + // or schedule getting next batch on nextTick + cursor.each(function (err, doc) { + if (err) { + return observer.onError(err); + } + if (!doc) { + return observer.onCompleted(); + } + observer.onNext(doc); + }); + + return Rx.Disposable.create(function () { + console.log('Disposing cursor...'); + cursor.close(); + }); + }); +} + +function saveUser(user) { + return Rx.Observable.create(function(observer) { + user.save(function(err) { + if (err) { + return observer.onError(err); + } + observer.onCompleted(); + }); + }); +} + +var count = 0; +createConnection(secrets.db) + .flatMap(function(db) { + return createQuery(db, 'users', {}); + }) + .map(function(user) { + assign(user, user.portfolio, user.profile); + return user; + }) + .flatMap(function(user) { + return saveUser(user); + }) + .count() + .subscribe( + function(_count) { + count = _count; + }, + function(err) { + console.log('an error occured', err); + }, + function() { + console.log('finished with %s documents processed', count); + } + ); From 28f273e7ee82dc75ebfe0bc8011e7de1f27384b9 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Sun, 7 Jun 2015 22:06:57 -0700 Subject: [PATCH 2/3] save users into new `user` collection --- seed/flattenUser.js | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/seed/flattenUser.js b/seed/flattenUser.js index a01ccfb420..f919d6b471 100644 --- a/seed/flattenUser.js +++ b/seed/flattenUser.js @@ -18,10 +18,10 @@ function createConnection(URI) { }); } -function createQuery(db, collection, selection, options, batchSize) { +function createQuery(db, collection, options, batchSize) { return Rx.Observable.create(function (observer) { console.log('Creating cursor...'); - var cursor = db.collection(collection).find(selection, options); + var cursor = db.collection(collection).find({}, options); cursor.batchSize(batchSize || 20); // Cursor.each will yield all doc from a batch in the same tick, // or schedule getting next batch on nextTick @@ -42,9 +42,9 @@ function createQuery(db, collection, selection, options, batchSize) { }); } -function saveUser(user) { +function insertMany(db, collection, users, options) { return Rx.Observable.create(function(observer) { - user.save(function(err) { + db.collection(collection).insertMany(users, options, function(err) { if (err) { return observer.onError(err); } @@ -54,21 +54,36 @@ function saveUser(user) { } var count = 0; -createConnection(secrets.db) +// will supply our db object +var dbObservable = createConnection(secrets.db).shareReplay(); +dbObservable .flatMap(function(db) { + // returns user document, n users per loop where n is the batchsize. return createQuery(db, 'users', {}); }) .map(function(user) { + // flatten user assign(user, user.portfolio, user.profile); return user; }) - .flatMap(function(user) { - return saveUser(user); + // batch them into arrays of twenty documents + .bufferWithCount(20) + // get bd object ready for insert + .withLatestFrom(dbObservable, function(users, db) { + return { + users: users, + db: db + }; }) + .flatMap(function(dats) { + // bulk insert into new collection for loopback + return insertMany(dats.db, 'user', dats.users, { w: 1 }); + }) + // count how many times insert completes .count() .subscribe( function(_count) { - count = _count; + count = _count * 20; }, function(err) { console.log('an error occured', err); From 78dac937f7bf7cc5484c9e7ff472cacb92bb2959 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Sun, 7 Jun 2015 22:07:38 -0700 Subject: [PATCH 3/3] remove email verification. --- server/boot/user.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/boot/user.js b/server/boot/user.js index 8f96d7204a..ec19a18f67 100644 --- a/server/boot/user.js +++ b/server/boot/user.js @@ -9,6 +9,12 @@ var _ = require('lodash'), secrets = require('../../config/secrets'); module.exports = function(app) { + // NOTE(berks): user email validation currently not needed but build in. This + // work around should let us sneak by + // see: + // https://github.com/strongloop/loopback/issues/1137#issuecomment-109200135 + delete app.models.User.validations.email; + var router = app.loopback.Router(); var User = app.models.User; var Story = app.models.Story;