From 7c2e7e439d92deb242abf559341510fb7cd3a9eb Mon Sep 17 00:00:00 2001 From: j1348 Date: Thu, 27 Dec 2018 19:06:21 +0100 Subject: [PATCH] Improve reduce with speed and filtering --- src/graphql/resolvers/index.js | 13 +---- src/graphql/resolvers/repo/index.js | 53 +++++++++++++---- src/graphql/resolvers/repo/model.js | 88 +++++++++++++++++------------ src/graphql/schema.js | 7 ++- src/importer.js | 2 +- 5 files changed, 102 insertions(+), 61 deletions(-) diff --git a/src/graphql/resolvers/index.js b/src/graphql/resolvers/index.js index 7ae643d..f87a066 100644 --- a/src/graphql/resolvers/index.js +++ b/src/graphql/resolvers/index.js @@ -2,18 +2,7 @@ import { getRepo, getReposFast } from './repo'; export default { Query: { - getRepos: getReposFast, + getRepos: (_, params) => getReposFast(params), getRepo: (_, { id }) => getRepo(id), }, - Repo: { - Ticks: ({ ticks }) => { - return ticks.map(({ stars, forks, date }) => { - return { - stars, - forks, - date, - }; - }); - }, - }, }; diff --git a/src/graphql/resolvers/repo/index.js b/src/graphql/resolvers/repo/index.js index c181fcf..4cf0510 100644 --- a/src/graphql/resolvers/repo/index.js +++ b/src/graphql/resolvers/repo/index.js @@ -7,13 +7,9 @@ export function getManyRepos(ids) { ); } -export function getRepoRefs() { - return Reporef.find({}); -} - export function getRepo(id) { return Repo.find({ _id: id }).map( - ({ _id: id, name, author, language, href, description }) => { + ({ _id: id, name, author, language, href, description, ticks }) => { return { id, name, @@ -21,13 +17,48 @@ export function getRepo(id) { language, href, description, + ticks, }; }, ); } -export function getReposFast() { - return getRepoRefs().then(data => { +export function getRepoRefs(filter) { + let query = {}; + if (filter) { + if (filter.from || filter.to) { + query = { 'value.dates': {} }; + if (filter.from) { + query['value.dates']['$gte'] = filter.from; + } + if (filter.to) { + query['value.dates']['$lte'] = filter.to; + } + } else if (filter.at) { + query = { 'value.dates': filter.at }; + } else if (filter.name) { + query = { 'value.name': filter.name }; + } else { + query = { 'value.date': new Date().toISOString().slice(0, 10) }; + } + } + return Reporef.find(query); +} + +function sortByDate(a, b) { + if (a.date < b.date) { + return 1; + } + + if (a.date > b.date) { + return -1; + } + + return 0; +} + +export function getReposFast(params) { + return getRepoRefs(params).then(data => { const ids = data.map(d => d._id); const metaInfo = data.reduce((result, { _doc: { value }, _id }) => { result[_id] = value; @@ -37,7 +68,7 @@ export function getReposFast() { return getManyRepos(ids).then(repos => { const newRepos = repos.map( ({ _id: id, name, description, author, language, href }) => { - const { date, stars, starsByDay } = metaInfo[id]; + const { stars, date, dates, speed } = metaInfo[id]; return { id, name, @@ -45,12 +76,14 @@ export function getReposFast() { author, language, href, - date, stars, - starsByDay, + date, + dates, + speed, }; }, ); + newRepos.sort(sortByDate); return newRepos; }); }); diff --git a/src/graphql/resolvers/repo/model.js b/src/graphql/resolvers/repo/model.js index e14fe52..92abd27 100644 --- a/src/graphql/resolvers/repo/model.js +++ b/src/graphql/resolvers/repo/model.js @@ -1,4 +1,3 @@ -import moment from 'moment'; import mongoose from 'mongoose'; const repoSchema = mongoose.Schema( @@ -31,14 +30,13 @@ ObjectId.prototype.valueOf = function() { return this.toString(); }; -repoSchema.index({ 'ticks.date': 1 }); +// repoSchema.index({ 'ticks.date': 1 }); const Repo = mongoose.model('Repo', repoSchema); const reporefSchema = mongoose.Schema({ - starsByDay: Number, + name: String, }); - const Reporef = mongoose.model('Reporef', reporefSchema); function reduceRepo() { @@ -48,42 +46,69 @@ function reduceRepo() { for (var i = 0; i < lastTicks.length; i++) { const t = lastTicks[i]; t.name = this.name; - t.id = this._id; - t.href = this.href; - t.language = this.language; + t.dates = t.date ? [t.date.toISOString().slice(0, 10)] : null; + // t.id = this._id; + // t.href = this.href; + // t.language = this.language; + // eslint-disable-next-line no-undef emit(this._id, t); } } function reduce(id, ticks) { - if (ticks.length < 2) { - return 0; + if (!ticks || ticks.length < 2) { + return null; } - var tick = ticks[0]; - var minStars = tick.stars; - var maxStars = minStars; - var minDate = tick.date; - var maxDate = ticks[ticks.length - 1].date; - var tmp = minStars; - - for (var i = 1; i < ticks.length; i++) { - tmp = ticks[i].stars; - if (tmp > maxStars) { - maxStars = tmp; - } else if (tmp < minStars) { - minStars = tmp; + const maxIndex = ticks.length - 1; + const stars = ticks[maxIndex].stars; + const name = ticks[maxIndex].name; // only to be query + const speed = {}; + const dates = []; + + const stringDate = ticks[maxIndex].date.toISOString(); + const date = stringDate.slice(0, 10); + + // if (ticks.length === 1) { + // dates.push(date); + // return { + // name, + // date, + // dates, + // ticks, + // stars, + // speed, + // }; + // } + + for (var i = 0, ii = 1; i < maxIndex; i++, ii++) { + if (!ticks[ii].date) { + continue; + } + const stringDate = ticks[ii].date.toISOString(); + const date = stringDate.slice(0, 10); + const hour = stringDate.slice(11, 16); + const time = + (new Date(ticks[ii].date).getTime() - + new Date(ticks[i].date).getTime()) / + 86400000; // 3600000 * 24); + speed[date] = speed[date] || {}; + speed[date][hour] = Math.round( + (ticks[ii].stars - ticks[i].stars) / time, + ); + + if (dates.indexOf(date) === -1) { + dates.push(date); } } return { - date: maxDate, - stars: maxStars, - starsByDay: Math.round( - (24 * 1000 * 3600 * (maxStars - minStars)) / - (maxDate - minDate), - ), + name, + date, + dates, + stars, + speed, }; } @@ -91,13 +116,6 @@ function reduceRepo() { { map: map.toString(), reduce: reduce.toString(), - query: { - 'ticks.date': { - $gte: moment() - .subtract(24, 'hour') - .toDate(), - }, - }, out: { replace: 'reporefs', inline: 1 }, }, (err, result) => { diff --git a/src/graphql/schema.js b/src/graphql/schema.js index 79e0950..721fa72 100644 --- a/src/graphql/schema.js +++ b/src/graphql/schema.js @@ -18,18 +18,19 @@ export default gql` name: String! language: String! description: String - starsByDay: Int href: String! - Ticks: [Tick] + ticks: [Tick] + speed: JSON stars: Int! forks: Int! date: Date + dates: [Date] createdAt: Date! updatedAt: Date! } type Query { - getRepos: [Repo] + getRepos(name: String, at: String, from: String, to: String): [Repo] getRepo(id: ID!): Repo } diff --git a/src/importer.js b/src/importer.js index 49e9e8f..c71abbd 100644 --- a/src/importer.js +++ b/src/importer.js @@ -125,5 +125,5 @@ module.exports = new CronJob({ }); if (process.env.NODE_ENV !== 'production') { - setTimeout(reduceRepo, 3000); + setTimeout(reduceRepo, 1000); }