Skip to content

Commit

Permalink
Общий метод popUserRegions для популяции регионов пользователя и сост…
Browse files Browse the repository at this point in the history
…авления запроса для выборки по регионам. Выборка публичных фото с четом такого запроса
  • Loading branch information
klimashkin committed Nov 10, 2013
1 parent 828d26a commit fb20ece
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 29 deletions.
6 changes: 4 additions & 2 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,13 @@ async.waterfall([
callback(null);
},
function loadingControllers(callback) {
var regionController;

require('./controllers/settings.js').loadController(app, db, io);
require('./controllers/mail.js').loadController(app);
require('./controllers/auth.js').loadController(app, db, io);
require('./controllers/index.js').loadController(app, db, io);
require('./controllers/region.js').loadController(app, db, io);
regionController = require('./controllers/region.js').loadController(app, db, io);
require('./controllers/photo.js').loadController(app, db, io);
require('./controllers/subscr.js').loadController(app, db, io);
require('./controllers/comment.js').loadController(app, db, io);
Expand All @@ -250,7 +252,7 @@ async.waterfall([
require('./controllers/errors.js').registerErrorHandling(app);
//require('./basepatch/v0.9.4.2.js').loadController(app, db);

callback(null);
regionController.fillCache(callback);
}
],
function finish(err) {
Expand Down
93 changes: 73 additions & 20 deletions controllers/_session.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function addUserSession(session) {

if (usObj === undefined) {
//Если пользователя еще нет в хеше пользователей, создаем объект и добавляем в хеш
us[user.login] = usid[user._id] = usObj = {user: user, sessions: {}};
us[user.login] = usid[user._id] = usObj = {user: user, sessions: {}, rquery: {}};
//При первом заходе пользователя присваиваем ему настройки по умолчанию
if (!user.settings) {
user.settings = {};
Expand Down Expand Up @@ -106,7 +106,7 @@ function authSocket(handshake, callback) {
if (session.user) {
//Если есть юзер, добавляем его в хеш пользователей
addUserSession(session);
session.user.populate({path: 'regions', select: {_id: 0, cid: 1, title_en: 1, title_local: 1}}, function (err, user) {
popUserRegions(session.user, function (err, user) {
if (err) {
return callback('Error: ' + err, false);
}
Expand Down Expand Up @@ -265,6 +265,57 @@ var checkWaitingSess = (function () {
};
}());

//Пупулируем регионы пользователя и строим запросы для них
function popUserRegions(user, cb) {
user.populate({path: 'regions', select: {_id: 0, cid: 1, title_en: 1, title_local: 1}}, function (err, user) {
if (err) {
return cb(err);
}
var rquery,
$orobj,
levels,
level,
region,
i;

if (user.regions.length) {
rquery = {$or: []};
levels = {};

//Формируем запрос для регионов
for (i = user.regions.length; i--;) {
region = regionController.regionCacheHash[user.regions[i].cid];
level = 'r' + region.parents.length;

if (levels[level] === undefined) {
levels[level] = [];
}
levels[level].push(region.cid);
}

for (i in levels) {
if (levels.hasOwnProperty(i)) {
level = levels[i];
$orobj = {};
if (level.length === 1) {
$orobj[i] = level[0];
} else if (level.length > 1) {
$orobj[i] = {$in: level};
}
rquery.$or.push($orobj);
}
}

if (rquery.$or.length === 1) {
rquery = rquery.$or[0];
}
//console.log(JSON.stringify(rquery));
us[user.login].rquery = rquery;
}

cb();
});
}
//Заново выбирает сессию из базы и популирует все зависимости. Заменяет ссылки в хешах на эти новые объекты
function regetSession(sessionCurrent, cb) {
Session.findOne({key: sessionCurrent.key}).populate('user').exec(function (err, session) {
Expand All @@ -274,7 +325,7 @@ function regetSession(sessionCurrent, cb) {
}

if (session.user) {
session.user.populate({path: 'regions', select: {_id: 0, cid: 1, title_en: 1, title_local: 1}}, function (err, user) {
popUserRegions(session.user, function (err, user) {
finish(err);
});
} else {
Expand All @@ -301,26 +352,28 @@ function regetSession(sessionCurrent, cb) {

//Заново выбирает пользователя из базы и популирует все зависимости. Заменяет ссылки в хешах на эти новые объекты
function regetUser(u, cb) {
User.findOne({login: u.login}).populate({path: 'regions', select: {_id: 0, cid: 1, title_en: 1, title_local: 1}}).exec(function (err, user) {
if (err || !user) {
console.log('Error wile regeting user (' + u.login + ')', err && err.message || 'No such user for reget');
cb(err || {message: 'No such user for reget'});
}
User.findOne({login: u.login}, function (err, user) {
popUserRegions(user, function (err, user) {
if (err || !user) {
console.log('Error wile regeting user (' + u.login + ')', err && err.message || 'No such user for reget');
cb(err || {message: 'No such user for reget'});
}

var usObj = us[user.login],
s;
var usObj = us[user.login],
s;

if (usObj) {
//Присваиваем новый объект пользователя usObj
usObj.user = user;
//Присваиваем новый объект пользователя всем его открытым сессиям
for (s in usObj.sessions) {
if (usObj.sessions.hasOwnProperty(s)) {
usObj.sessions[s].user = user;
if (usObj) {
//Присваиваем новый объект пользователя usObj
usObj.user = user;
//Присваиваем новый объект пользователя всем его открытым сессиям
for (s in usObj.sessions) {
if (usObj.sessions.hasOwnProperty(s)) {
usObj.sessions[s].user = user;
}
}
}
}
cb(null, user);
cb(null, user);
});
});
}

Expand Down Expand Up @@ -397,7 +450,7 @@ function regen(session, data, keyRegen, userRePop, cb) {
//https://github.com/LearnBoost/mongoose/issues/1530
if (userRePop && session.user) {
session.populate('user', function (err, session) {
session.user.populate({path: 'regions', select: {_id: 0, cid: 1, title_en: 1, title_local: 1}}, function (err, user) {
popUserRegions(session.user, function (err, user) {
if (cb) {
cb(err, session);
}
Expand Down
13 changes: 9 additions & 4 deletions controllers/photo.js
Original file line number Diff line number Diff line change
Expand Up @@ -601,18 +601,23 @@ function givePhotosPublic(iAm, data, cb) {

var skip = Math.abs(Number(data.skip)) || 0,
limit = Math.min(data.limit || 40, 100),
filter = data.filter;
filter = data.filter || {};

step(
function () {
var query = {},
regions,
i,
fieldsSelect = iAm ? compactFieldsId : compactFields;

if (filter) {
if (filter.nogeo) {
query.geo = null;
if (filter.nogeo) {
query.geo = null;
} else {
if (iAm) {
_.assign(query, _session.us[iAm.login].rquery);
}
}
console.log(query);
Photo.find(query, fieldsSelect, {lean: true, skip: skip, limit: limit, sort: {adate: -1}}, this.parallel());
Photo.count(query, this.parallel());
},
Expand Down
33 changes: 32 additions & 1 deletion controllers/region.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,34 @@ var auth = require('./auth.js'),
Utils = require('../commons/Utils.js'),
msg = {
deny: 'You do not have permission for this action'
};
},
logger = require('log4js').getLogger("region.js"),
loggerApp = require('log4js').getLogger("app.js"),

regionCacheHash = {}, //Хэш-кэш регионов из базы 'cid': {_id, cid, parents}
regionCacheArr = []; //Массив-кэш регионов из базы [{_id, cid, parents}]

function fillCache(cb) {
Region.find({}, {_id: 1, cid: 1, parents: 1, title_en: 1, title_local: 1}, {lean: true}, function (err, regions) {
if (err) {
logger.error('FillCache: ' + err.message);
if (cb) {
cb(err);
}
return;
}
for (var i = regions.length; i--;) {
regionCacheHash[regions[i].cid] = regions[i];
}
regionCacheArr = regions;

logger.info('Region cache filled with ' + regions.length);
loggerApp.info('Region cache filled with ' + regions.length);
if (cb) {
cb();
}
});
}

function saveRegion(socket, data, cb) {
var iAm = socket.handshake.session.user;
Expand Down Expand Up @@ -499,7 +526,11 @@ module.exports.loadController = function (app, db, io) {
});
});

return module.exports;
};
module.exports.fillCache = fillCache;
module.exports.regionCacheHash = regionCacheHash;
module.exports.regionCacheArr = regionCacheArr;
module.exports.getRegionsByGeoPoint = getRegionsByGeoPoint;
module.exports.getOrderedRegionList = getOrderedRegionList;
module.exports.getObjRegionList = getObjRegionList;
Expand Down
12 changes: 10 additions & 2 deletions log4js.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,26 @@
"type": "file",
"filename": "app.log",
"maxLogSize": 524288,
"backups": 1,
"backups": 2,
"pollInterval": 10,
"category": ["app.js", "systemjs.js"]
},
{
"type": "file",
"filename": "common.log",
"maxLogSize": 524288,
"backups": 1,
"backups": 2,
"pollInterval": 15,
"category": ["console", "index.js", "profile.js", "auth.js", "photo.js", "photoCluster.js"]
},
{
"type": "file",
"filename": "region.log",
"maxLogSize": 524288,
"backups": 1,
"pollInterval": 15,
"category": ["region.js"]
},
{
"type": "file",
"filename": "404.log",
Expand Down
5 changes: 5 additions & 0 deletions models/Photo.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ PhotoSchema_Del.virtual('del').get(function () {
//В основной коллекции фотографий индексируем выборку координат по годам для выборки на карте
//Compound index http://docs.mongodb.org/manual/core/geospatial-indexes/#compound-geospatial-indexes
PhotoSchema.index({ g: '2d', year: 1});
PhotoSchema.index({ r0: 1, adate: 1});
PhotoSchema.index({ r1: 1, adate: 1});
PhotoSchema.index({ r2: 1, adate: 1});
PhotoSchema.index({ r3: 1, adate: 1});
PhotoSchema.index({ r4: 1, adate: 1});


PhotoSchema.pre('save', preSave);
Expand Down

0 comments on commit fb20ece

Please sign in to comment.