Refactor server side search to use objects for params to tidy things up

This commit is contained in:
Andrew Kingston 2021-05-14 15:41:26 +01:00
parent 861c9b3b5a
commit 82b64dcd1f
2 changed files with 56 additions and 111 deletions

View File

@ -6,38 +6,13 @@ exports.rowSearch = async ctx => {
const appId = ctx.appId const appId = ctx.appId
const { tableId } = ctx.params const { tableId } = ctx.params
const db = new CouchDB(appId) const db = new CouchDB(appId)
const { const { paginate, query, ...params } = ctx.request.body
bookmark,
query,
limit,
sort,
sortOrder,
sortType,
paginate,
} = ctx.request.body
let response let response
if (paginate) { if (paginate) {
response = await paginatedSearch( response = await paginatedSearch(appId, query, params)
appId,
query,
tableId,
sort,
sortOrder,
sortType,
limit,
bookmark
)
} else { } else {
response = await fullSearch( response = await fullSearch(appId, query, params)
appId,
query,
tableId,
sort,
sortOrder,
sortType,
limit
)
} }
// Enrich search results with relationships // Enrich search results with relationships

View File

@ -206,38 +206,34 @@ const runQuery = async query => {
* until enough results have been found. * until enough results have been found.
* @param appId {string} The app ID to search * @param appId {string} The app ID to search
* @param query {object} The JSON query structure * @param query {object} The JSON query structure
* @param tableId {string} The table ID to search * @param params {object} The search params including:
* @param sort {string} The sort column * tableId {string} The table ID to search
* @param sortOrder {string} The sort order ("ascending" or "descending") * sort {string} The sort column
* @param sortType {string} Whether to treat sortable values as strings or * sortOrder {string} The sort order ("ascending" or "descending")
* numbers. ("string" or "number") * sortType {string} Whether to treat sortable values as strings or
* @param limit {number} The number of results to fetch * numbers. ("string" or "number")
* @param bookmark {string|null} Current bookmark in the recursive search * limit {number} The number of results to fetch
* @param rows {array|null} Current results in the recursive search * bookmark {string|null} Current bookmark in the recursive search
* rows {array|null} Current results in the recursive search
* @returns {Promise<*[]|*>} * @returns {Promise<*[]|*>}
*/ */
const recursiveSearch = async ( const recursiveSearch = async (appId, query, params) => {
appId, const bookmark = params.bookmark
query, const rows = params.rows || []
tableId, if (rows.length >= params.limit) {
sort,
sortOrder,
sortType,
limit,
bookmark = null,
rows = []
) => {
if (rows.length >= limit) {
return rows return rows
} }
const pageSize = rows.length > limit - 200 ? limit - rows.length : 200 let pageSize = 200
if (rows.length > params.limit - 200) {
pageSize = params.limit - rows.length
}
const url = new QueryBuilder(appId, query) const url = new QueryBuilder(appId, query)
.setTable(tableId) .setTable(params.tableId)
.setBookmark(bookmark) .setBookmark(bookmark)
.setLimit(pageSize) .setLimit(pageSize)
.setSort(sort) .setSort(params.sort)
.setSortOrder(sortOrder) .setSortOrder(params.sortOrder)
.setSortType(sortType) .setSortType(params.sortType)
.buildSearchURL() .buildSearchURL()
const page = await runQuery(url) const page = await runQuery(url)
if (!page.rows.length) { if (!page.rows.length) {
@ -246,17 +242,12 @@ const recursiveSearch = async (
if (page.rows.length < 200) { if (page.rows.length < 200) {
return [...rows, ...page.rows] return [...rows, ...page.rows]
} }
return await recursiveSearch( const newParams = {
appId, ...params,
query, bookmark: page.bookmark,
tableId, rows: [...rows, ...page.rows],
sort, }
sortOrder, return await recursiveSearch(appId, query, newParams)
sortType,
limit,
page.bookmark,
[...rows, ...page.rows]
)
} }
/** /**
@ -265,36 +256,29 @@ const recursiveSearch = async (
* paginated search. * paginated search.
* @param appId {string} The app ID to search * @param appId {string} The app ID to search
* @param query {object} The JSON query structure * @param query {object} The JSON query structure
* @param tableId {string} The table ID to search * @param params {object} The search params including:
* @param sort {string} The sort column * tableId {string} The table ID to search
* @param sortOrder {string} The sort order ("ascending" or "descending") * sort {string} The sort column
* @param sortType {string} Whether to treat sortable values as strings or * sortOrder {string} The sort order ("ascending" or "descending")
* numbers. ("string" or "number") * sortType {string} Whether to treat sortable values as strings or
* @param limit {number} The desired page size * numbers. ("string" or "number")
* @param bookmark {string} The bookmark to resume from * limit {number} The desired page size
* bookmark {string} The bookmark to resume from
* @returns {Promise<{hasNextPage: boolean, rows: *[]}>} * @returns {Promise<{hasNextPage: boolean, rows: *[]}>}
*/ */
exports.paginatedSearch = async ( exports.paginatedSearch = async (appId, query, params) => {
appId, let limit = params.limit
query,
tableId,
sort,
sortOrder,
sortType,
limit,
bookmark
) => {
if (limit == null || isNaN(limit) || limit < 0) { if (limit == null || isNaN(limit) || limit < 0) {
limit = 50 limit = 50
} }
limit = Math.min(limit, 200) limit = Math.min(limit, 200)
const builder = new QueryBuilder(appId, query) const builder = new QueryBuilder(appId, query)
.setTable(tableId) .setTable(params.tableId)
.setSort(sort) .setSort(params.sort)
.setSortOrder(sortOrder) .setSortOrder(params.sortOrder)
.setSortType(sortType) .setSortType(params.sortType)
const searchUrl = builder const searchUrl = builder
.setBookmark(bookmark) .setBookmark(params.bookmark)
.setLimit(limit) .setLimit(limit)
.buildSearchURL() .buildSearchURL()
const searchResults = await runQuery(searchUrl) const searchResults = await runQuery(searchUrl)
@ -320,35 +304,21 @@ exports.paginatedSearch = async (
* handling too much data. * handling too much data.
* @param appId {string} The app ID to search * @param appId {string} The app ID to search
* @param query {object} The JSON query structure * @param query {object} The JSON query structure
* @param tableId {string} The table ID to search * @param params {object} The search params including:
* @param sort {string} The sort column * tableId {string} The table ID to search
* @param sortOrder {string} The sort order ("ascending" or "descending") * sort {string} The sort column
* @param sortType {string} Whether to treat sortable values as strings or * sortOrder {string} The sort order ("ascending" or "descending")
* numbers. ("string" or "number") * sortType {string} Whether to treat sortable values as strings or
* @param limit {number} The desired number of results * numbers. ("string" or "number")
* limit {number} The desired number of results
* @returns {Promise<{rows: *}>} * @returns {Promise<{rows: *}>}
*/ */
exports.fullSearch = async ( exports.fullSearch = async (appId, query, params) => {
appId, let limit = params.limit
query,
tableId,
sort,
sortOrder,
sortType,
limit
) => {
if (limit == null || isNaN(limit) || limit < 0) { if (limit == null || isNaN(limit) || limit < 0) {
limit = 1000 limit = 1000
} }
limit = Math.min(limit, 1000) params.limit = Math.min(limit, 1000)
const rows = await recursiveSearch( const rows = await recursiveSearch(appId, query, params)
appId,
query,
tableId,
sort,
sortOrder,
sortType,
limit
)
return { rows } return { rows }
} }