From 3f9517c542acbde5fd6fd5afed5434a04e11a7b8 Mon Sep 17 00:00:00 2001 From: Selim Mustafaev Date: Thu, 7 Jan 2021 16:46:01 +0300 Subject: [PATCH] Search pagination --- index.js | 2 -- migration.js | 27 +++++++++++++++++++++++++++ models/vehicle.js | 3 +++ package.json | 3 ++- routes/events.js | 5 +++-- routes/vehicles.js | 29 ++++++++++++++++++++++++++--- 6 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 migration.js diff --git a/index.js b/index.js index 233c326..53a624b 100644 --- a/index.js +++ b/index.js @@ -16,8 +16,6 @@ const dotenvExpand = require('dotenv-expand'); let dotenvConf = dotenv.config(); dotenvExpand(dotenvConf); -console.log(process.env); - app.use(compression()); app.use(bodyParser.json()); app.use(expressMongoDb(process.env.MONGO_CONNECTION_STRING)); diff --git a/migration.js b/migration.js new file mode 100644 index 0000000..d9e3a39 --- /dev/null +++ b/migration.js @@ -0,0 +1,27 @@ +const MongoClient = require('mongodb').MongoClient; +const dotenv = require('dotenv'); +const dotenvExpand = require('dotenv-expand'); + +let dotenvConf = dotenv.config(); +dotenvExpand(dotenvConf); + +async function addUpdatedDate() { + let client = await MongoClient.connect(process.env.MONGO_CONNECTION_STRING, { useUnifiedTopology: true }); + let db = client.db('autocatdev'); + let collection = db.collection('vehicles'); + let vehicles = await collection.find().toArray(); + for(let vehicle of vehicles) { + let updatedDate = vehicle.addedDate; + if(vehicle.events.length > 0) { + let lastEvent = vehicle.events.reduce((acc, cur) => acc.date > cur.date ? acc : cur); + updatedDate = Math.max(1000*lastEvent.date, vehicle.addedDate); + } + console.log(updatedDate); + await collection.updateOne({ _id: vehicle._id }, { $set: { updatedDate } }); + } +} + +(async () => { + await addUpdatedDate(); + console.log('====== Done ======'); +})(); \ No newline at end of file diff --git a/models/vehicle.js b/models/vehicle.js index 521495e..913f88e 100644 --- a/models/vehicle.js +++ b/models/vehicle.js @@ -59,6 +59,7 @@ class Vehicle { v.isJapanese = report.is_japanese_vehicle; v.addedDate = Date.now(); + v.updatedDate = v.addedDate; v.events = []; v.debugInfo = { @@ -102,6 +103,7 @@ class Vehicle { }); v.addedDate = Date.now(); + v.updatedDate = v.addedDate; v.events = []; v.debugInfo = { @@ -163,6 +165,7 @@ class Vehicle { }); v.addedDate = Date.now(); + v.updatedDate = v.addedDate; v.events = []; v.debugInfo = { diff --git a/package.json b/package.json index 5edf649..b9be8af 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "AutoCat app backend", "main": "index.js", "scripts": { - "server": "node --async-stack-traces --trace-warnings index.js", + "server": "node --async-stack-traces --trace-warnings index.js", + "migration": "node --async-stack-traces --trace-warnings migration.js", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Selim Mustafaev", diff --git a/routes/events.js b/routes/events.js index 713e398..802ce85 100644 --- a/routes/events.js +++ b/routes/events.js @@ -12,6 +12,7 @@ router.post('/', async (req, res) => { event.id = uuidv4(); let collection = req.db.collection('vehicles'); await collection.updateOne({ number }, { $push: { events: event } }); + await collection.updateOne({ number }, { $set: { updatedDate: Date.now() } }); let vehicle = await collection.findOne({ number }); if(vehicle) { res.send({ success: true, data: vehicle }); @@ -34,7 +35,7 @@ router.delete('/', async (req, res) => { let index = vehicle.events.findIndex(e => e.id == eventId); if(index >= 0) { vehicle.events.splice(index, 1); - await collection.updateOne({ number: vehicle.number }, { $set: { events: vehicle.events } }); + await collection.updateOne({ number: vehicle.number }, { $set: { events: vehicle.events, updatedDate: Date.now() } }); } res.send({ success: true, data: vehicle }); } else { @@ -56,7 +57,7 @@ router.put('/', async (req, res) => { let index = vehicle.events.findIndex(e => e.id == event.id); if(index >= 0) { vehicle.events[index] = event; - await collection.updateOne({ number: vehicle.number }, { $set: { events: vehicle.events } }); + await collection.updateOne({ number: vehicle.number }, { $set: { events: vehicle.events, updatedDate: Date.now() } }); res.send({ success: true, data: vehicle }); } else { res.send(makeError('Event not found')); diff --git a/routes/vehicles.js b/routes/vehicles.js index 2c05193..f70a951 100644 --- a/routes/vehicles.js +++ b/routes/vehicles.js @@ -8,6 +8,7 @@ const { regions } = require('../data_providers/constants'); const RsaProvider = require('../data_providers/rsa'); const NomerogramProvider = require('../data_providers/nomerogram'); const Utils = require('../utils'); +const ObjectId = require('mongodb').ObjectID; const makeError = error => ({ success: false, error }); @@ -81,6 +82,7 @@ router.post('/check', async (req, res) => { // In case of force update of existing vehicle, transfer all events to the new DB record if (vehicles.length > 0) { + vehicle.addedDate = vehicles[0].addedDate; vehicle.events = vehicles[0].events; vehicle.osagoContracts = vehicles[0].osagoContracts; } @@ -95,14 +97,35 @@ router.post('/check', async (req, res) => { }); router.get('/', async (req, res) => { - const { limit } = req.query; const { email } = req.user; + const { pageToken } = req.query; + const pageSize = 50; try { let finalQuery = Utils.makeVehiclesSearchQuery(req.query, email); let collection = req.db.collection('vehicles'); - let vehicles = await collection.find(finalQuery).sort({ addedDate: -1 }).limit(parseInt(limit ?? 0)).toArray(); - res.send({ success: true, data: vehicles }); + + let response = {}; + if(!pageToken) { + response.count = await collection.countDocuments(finalQuery); + } else { + let lastVehicle = await collection.findOne({ _id: ObjectId(pageToken) }); + finalQuery.$or = [ + { updatedDate: { $lt: lastVehicle.updatedDate } }, + { + updatedDate: lastVehicle.updatedDate, + _id: { $lt: ObjectId(pageToken) } + } + ]; + } + + let vehicles = await collection.find(finalQuery).sort({ updatedDate: -1 }).limit(pageSize).toArray(); + if(vehicles.length == pageSize) { + response.pageToken = vehicles[vehicles.length - 1]._id; + } + response.items = vehicles; + + res.send({ success: true, data: response }); } catch(ex) { res.send(makeError('Error reading vehicles from DB')); console.error(ex);