Speedup group list even more, implement basic text search

master
Vitaliy Filippov 2016-10-09 18:52:28 +03:00
parent 4ec979569b
commit 6abd931751
1 changed files with 36 additions and 27 deletions

View File

@ -101,21 +101,30 @@ function ymd(dt)
SyncerWeb.prototype.msgSearchCond = function(query) SyncerWeb.prototype.msgSearchCond = function(query)
{ {
var p; var p = [];
if (query.folderId) if (query.folderId)
p = this.pg.sql.eq('m.folder_id', query.folderId); p.push(this.pg.sql.eq('m.folder_id', query.folderId));
else if (query.folderType == 'unread') else if (query.folderType == 'unread')
p = this.pg.sql('(flags @> array[\'unread\']::varchar(255)[])'); p.push(this.pg.sql('(flags @> array[\'unread\']::varchar(255)[])'));
else if (query.folderType == 'pinned') else if (query.folderType == 'pinned')
p = this.pg.sql('(flags @> array[\'flagged\']::varchar(255)[])'); p.push(this.pg.sql('(flags @> array[\'flagged\']::varchar(255)[])'));
else if (query.folderType == 'inbox') else if (query.folderType == 'inbox')
p = this.pg.sql('(flags @> array[\'in\']::varchar(255)[])'); {
var folders = [];
for (var id in this.syncer.accounts)
{
n = this.syncer.accounts[id].settings.folders.spam;
if (n)
folders.push(this.pg.sql.and({ 'f.name': n, 'f.account_id': id }));
}
p.push(this.pg.sql.not(this.pg.sql.or.apply(this.pg.sql, folders)));
p.push(this.pg.sql('(flags @> array[\'in\']::varchar(255)[])'));
}
else if (query.folderType == 'out') else if (query.folderType == 'out')
p = this.pg.sql('(flags @> array[\'out\']::varchar(255)[])'); p.push(this.pg.sql('(flags @> array[\'out\']::varchar(255)[])'));
else if (query.folderType == 'outbox') else if (query.folderType == 'outbox')
{ {
// TODO это какая-то хитрая метапапка, которая не живёт на IMAP'е? // TODO это какая-то хитрая метапапка, которая не живёт на IMAP'е?
p = null;
} }
else if (query.folderType == 'drafts' || query.folderType == 'spam' || query.folderType == 'trash') else if (query.folderType == 'drafts' || query.folderType == 'spam' || query.folderType == 'trash')
{ {
@ -127,11 +136,13 @@ SyncerWeb.prototype.msgSearchCond = function(query)
if (n) if (n)
folders.push(this.pg.sql.and({ 'f.name': n, 'f.account_id': id })); folders.push(this.pg.sql.and({ 'f.name': n, 'f.account_id': id }));
} }
p = this.pg.sql.or.apply(this.pg.sql.or, folders); p.push(this.pg.sql.or.apply(this.pg.sql, folders));
} }
if (p && query.accountId) if (typeof query.search == 'string' && query.search.trim())
p = this.pg.sql.and(p, this.pg.sql.eq('f.account_id', query.accountId)); p.push(this.pg.sql('messages_fulltext(m) @@ plainto_tsquery($1)', query.search.trim()));
return p; if (query.accountId)
p.push(this.pg.sql.and(p, this.pg.sql.eq('f.account_id', query.accountId)));
return p.length ? this.pg.sql.and.apply(this.pg.sql, p) : null;
} }
SyncerWeb.prototype.get_groups = function*(req, res) SyncerWeb.prototype.get_groups = function*(req, res)
@ -159,29 +170,27 @@ SyncerWeb.prototype.get_groups = function*(req, res)
{ {
intervals.push({ date: ymd(new Date(i)), name: 'd'+d }); intervals.push({ date: ymd(new Date(i)), name: 'd'+d });
} }
for (var i = today.getFullYear()-1; i >= 1970; i--)
{
intervals.unshift({ date: i+'-01-01', name: ''+i });
}
intervals.push({ date: ymd(today), name: 't' }); intervals.push({ date: ymd(today), name: 't' });
for (var i = 0; i < intervals.length-1; i++) for (var i = 0; i < intervals.length-1; i++)
{ {
intervals[i].date_end = intervals[i+1].date; intervals[i].date_end = intervals[i+1].date;
} }
intervals[i].date_end = '100000-12-31'; // it's faster than (is null or <) intervals[intervals.length-1].date_end = '100000-12-31'; // it's faster than (is null or <)
var [ groups ] = yield this.pg var [ groups ] = yield this.pg
.select('d.name, d.date, count(*) count') .select('d.name, d.date, ('+
.from('messages m') this.pg.select('count(*)')
.innerJoin('folders f', this.pg.sql('f.id=m.folder_id')) .from('messages m')
.innerJoin(this.pg.sql.values(intervals).as('d').columns(), .innerJoin('folders f', this.pg.sql('f.id=m.folder_id'))
this.pg.sql('m.time >= d.date::date and m.time < d.date_end::date')) .where(cond)
.where(cond) .where(this.pg.sql('m.time >= d.date::date and m.time < d.date_end::date'))
.groupBy('1, 2') +') count')
.union( .from(this.pg.sql.values(intervals).as('d').columns())
this.pg.select('y::text as name, y||\'-01-01\' date, ('+
this.pg.select('count(*)').from('messages m')
.innerJoin('folders f', this.pg.sql('f.id=m.folder_id'))
.where(cond).where(this.pg.sql('m.time >= (t.y||\'-01-01\')::date and m.time <= (t.y||\'-12-31\')::date'))
+') count')
.from('generate_series(1970, '+(today.getFullYear()-1)+') as t (y)')
)
.orderBy('date desc').rows(gen.ef()); .orderBy('date desc').rows(gen.ef());
groups = groups.filter(g => g.count > 0);
return res.send({ groups: groups }); return res.send({ groups: groups });
} }