diff --git a/package-lock.json b/package-lock.json index 677b5631c..b7fdb5148 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9937,6 +9937,11 @@ "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" }, + "slugify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.4.0.tgz", + "integrity": "sha512-FtLNsMGBSRB/0JOE2A0fxlqjI6fJsgHGS13iTuVT28kViI4JjUiNqp/vyis0ZXYcMnpR3fzGNkv+6vRlI2GwdQ==" + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", diff --git a/package.json b/package.json index e563a5913..3900eaea9 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,8 @@ "mongoose-paginate": "5.0.3", "ms": "2.1.2", "pino": "6.0.0", - "pino-elasticsearch": "4.4.0" + "pino-elasticsearch": "4.4.0", + "slugify": "1.4.0" }, "engines": { "node": "10.17.0", diff --git a/src/app/routes/v1/fills.js b/src/app/routes/v1/fills.js index 97b328bbb..6acd4d098 100644 --- a/src/app/routes/v1/fills.js +++ b/src/app/routes/v1/fills.js @@ -3,6 +3,7 @@ const moment = require('moment'); const mongoose = require('mongoose'); const Router = require('koa-router'); +const { logSearch } = require('../../../search'); const Fill = require('../../../model/fill'); const getRelayerLookupId = require('../../../relayers/get-relayer-lookup-id'); const InvalidParameterError = require('../../errors/invalid-parameter-error'); @@ -138,23 +139,26 @@ const createRouter = () => { ); } - const { docs, pages, total } = await searchFills( - { - address, - bridgeAddress, - bridged, - dateFrom, - dateTo, - protocolVersion, - query, - relayerId: relayerLookupId, - status: reverseMapStatus(status), - token, - valueFrom, - valueTo, - }, - { limit, page }, - ); + const [{ docs, pages, total }] = await Promise.all([ + searchFills( + { + address, + bridgeAddress, + bridged, + dateFrom, + dateTo, + protocolVersion, + query, + relayerId: relayerLookupId, + status: reverseMapStatus(status), + token, + valueFrom, + valueTo, + }, + { limit, page }, + ), + query !== undefined ? logSearch(query, new Date()) : Promise.resolve(), + ]); response.body = { fills: transformFills(docs), diff --git a/src/search/index.js b/src/search/index.js new file mode 100644 index 000000000..5ead8433b --- /dev/null +++ b/src/search/index.js @@ -0,0 +1,3 @@ +const logSearch = require('./log-search'); + +module.exports = { logSearch }; diff --git a/src/search/log-search.js b/src/search/log-search.js new file mode 100644 index 000000000..4a371da52 --- /dev/null +++ b/src/search/log-search.js @@ -0,0 +1,33 @@ +const slugify = require('slugify'); + +const elasticsearch = require('../util/elasticsearch'); + +const logSearch = async (terms, date) => { + const year = date.getUTCFullYear(); + const month = date.getUTCMonth(); + const day = date.getUTCDate(); + const hour = date.getUTCHours(); + const logDate = new Date(); + + logDate.setTime(Date.UTC(year, month, day, hour)); + + const slug = slugify(terms, { replacement: '_', lower: true, strict: true }); + + await elasticsearch.getClient().update({ + id: `${year}_${month + 1}_${day}_${hour}_${slug}`, + index: 'search_terms', + body: { + script: { + lang: 'painless', + source: 'ctx._source.hits += 1', + }, + upsert: { + date: logDate, + hits: 1, + terms, + }, + }, + }); +}; + +module.exports = logSearch;