Some final changes to search system so that the new indexing system is used instead of mango to achieve exactly the same result.

This commit is contained in:
mike12345567 2021-03-26 13:46:20 +00:00
parent b97071bf82
commit 97f8d34947
5 changed files with 71 additions and 44 deletions

View File

@ -17,7 +17,7 @@ const {
const { FieldTypes } = require("../../constants") const { FieldTypes } = require("../../constants")
const { isEqual } = require("lodash") const { isEqual } = require("lodash")
const { cloneDeep } = require("lodash/fp") const { cloneDeep } = require("lodash/fp")
const searchController = require("./search") const { QueryBuilder, search } = require("./search/utils")
const TABLE_VIEW_BEGINS_WITH = `all${SEPARATOR}${DocumentTypes.TABLE}${SEPARATOR}` const TABLE_VIEW_BEGINS_WITH = `all${SEPARATOR}${DocumentTypes.TABLE}${SEPARATOR}`
@ -264,13 +264,17 @@ exports.search = async function(ctx) {
} = ctx.request.body } = ctx.request.body
const tableId = ctx.params.tableId const tableId = ctx.params.tableId
const queryBuilder = new searchController.QueryBuilder(appId) const queryBuilder = new QueryBuilder(appId)
.setLimit(pageSize) .setLimit(pageSize)
.addTable(tableId) .addTable(tableId)
if (bookmark) { if (bookmark) {
queryBuilder.setBookmark(bookmark) queryBuilder.setBookmark(bookmark)
} }
let searchString
if (ctx.query.raw && ctx.query.raw !== "") {
searchString = queryBuilder.complete(query["RAW"])
} else {
// make all strings a starts with operation rather than pure equality // make all strings a starts with operation rather than pure equality
for (const [key, queryVal] of Object.entries(query)) { for (const [key, queryVal] of Object.entries(query)) {
if (typeof queryVal === "string") { if (typeof queryVal === "string") {
@ -279,8 +283,10 @@ exports.search = async function(ctx) {
queryBuilder.addEqual(key, queryVal) queryBuilder.addEqual(key, queryVal)
} }
} }
searchString = queryBuilder.complete()
}
const response = await searchController.search(queryBuilder.complete()) const response = await search(searchString)
// delete passwords from users // delete passwords from users
if (tableId === ViewNames.USERS) { if (tableId === ViewNames.USERS) {

View File

@ -0,0 +1,18 @@
const { QueryBuilder, buildSearchUrl, search } = require("./utils")
exports.rowSearch = async ctx => {
// this can't be done through pouch, have to reach for trusty node-fetch
const appId = ctx.user.appId
const bookmark = ctx.params.bookmark
let url
if (ctx.params.query) {
url = new QueryBuilder(appId, ctx.params.query, bookmark).complete()
} else if (ctx.params.raw) {
url = buildSearchUrl({
appId,
query: ctx.params.raw,
bookmark,
})
}
ctx.body = await search(url)
}

View File

@ -1,22 +1,24 @@
const { SearchIndexes } = require("../../../db/utils")
const { checkSlashesInUrl } = require("../../../utilities")
const env = require("../../../environment")
const fetch = require("node-fetch") const fetch = require("node-fetch")
const { SearchIndexes } = require("../../db/utils")
const { checkSlashesInUrl } = require("../../utilities")
const env = require("../../environment")
function buildSearchUrl( /**
appId, * Given a set of inputs this will generate the URL which is to be sent to the search proxy in CouchDB.
query, * @param {string} appId The ID of the app which we will be searching within.
bookmark = null, * @param {string} query The lucene query string which is to be used for searching.
limit = 50, * @param {string|null} bookmark If there were more than the limit specified can send the bookmark that was
includeDocs = true * returned with query for next set of search results.
) { * @param {number} limit The number of entries to return per query.
* @param {boolean} excludeDocs By default full rows are returned, if required this can be disabled.
* @return {string} The URL which a GET can be performed on to receive results.
*/
function buildSearchUrl({ appId, query, bookmark, excludeDocs, limit = 50 }) {
let url = `${env.COUCH_DB_URL}/${appId}/_design/database/_search` let url = `${env.COUCH_DB_URL}/${appId}/_design/database/_search`
url += `/${SearchIndexes.ROWS}?q=${query}` url += `/${SearchIndexes.ROWS}?q=${query}`
if (includeDocs) {
url += "&include_docs=true"
}
if (limit) {
url += `&limit=${limit}` url += `&limit=${limit}`
if (!excludeDocs) {
url += "&include_docs=true"
} }
if (bookmark) { if (bookmark) {
url += `&bookmark=${bookmark}` url += `&bookmark=${bookmark}`
@ -77,7 +79,7 @@ class QueryBuilder {
return this return this
} }
complete() { complete(rawQuery = null) {
let output = "" let output = ""
function build(structure, queryFn) { function build(structure, queryFn) {
for (let [key, value] of Object.entries(structure)) { for (let [key, value] of Object.entries(structure)) {
@ -101,12 +103,18 @@ class QueryBuilder {
if (this.query.fuzzy) { if (this.query.fuzzy) {
build(this.query.fuzzy, (key, value) => `${key}:${value}~`) build(this.query.fuzzy, (key, value) => `${key}:${value}~`)
} }
return buildSearchUrl(this.appId, output, this.bookmark, this.limit) if (rawQuery) {
output = output.length === 0 ? rawQuery : `&${rawQuery}`
}
return buildSearchUrl({
appId: this.appId,
query: output,
bookmark: this.bookmark,
limit: this.limit,
})
} }
} }
exports.QueryBuilder = QueryBuilder
exports.search = async query => { exports.search = async query => {
const response = await fetch(query, { const response = await fetch(query, {
method: "GET", method: "GET",
@ -124,15 +132,5 @@ exports.search = async query => {
return output return output
} }
exports.rowSearch = async ctx => { exports.QueryBuilder = QueryBuilder
// this can't be done through pouch, have to reach for trusty node-fetch exports.buildSearchUrl = buildSearchUrl
const appId = ctx.user.appId
const bookmark = ctx.params.bookmark
let url
if (ctx.params.query) {
url = new QueryBuilder(appId, ctx.params.query, bookmark).complete()
} else if (ctx.params.raw) {
url = buildSearchUrl(appId, ctx.params.raw, bookmark)
}
ctx.body = await exports.search(url)
}

View File

@ -27,7 +27,7 @@ const EventType = {
} }
exports.EventType = EventType exports.EventType = EventType
// re-export utils here for ease of use // re-export search here for ease of use
exports.IncludeDocs = IncludeDocs exports.IncludeDocs = IncludeDocs
exports.getLinkDocuments = getLinkDocuments exports.getLinkDocuments = getLinkDocuments
exports.createLinkView = createLinkView exports.createLinkView = createLinkView

View File

@ -48,7 +48,6 @@
if (table) { if (table) {
const tableDef = await API.fetchTableDefinition(table) const tableDef = await API.fetchTableDefinition(table)
schema = tableDef.schema schema = tableDef.schema
lastBookmark = mark
const output = await API.searchTableData({ const output = await API.searchTableData({
tableId: table, tableId: table,
search: parsedSearch, search: parsedSearch,
@ -70,7 +69,13 @@
function previousPage() { function previousPage() {
nextBookmark = bookmark nextBookmark = bookmark
if (lastBookmark !== bookmark) {
bookmark = lastBookmark bookmark = lastBookmark
} else {
// special case for going back to beginning
bookmark = null
lastBookmark = null
}
} }
</script> </script>
@ -135,10 +140,10 @@
{/if} {/if}
{/if} {/if}
<div class="pagination"> <div class="pagination">
{#if bookmark != null} {#if lastBookmark != null || bookmark != null}
<Button primary on:click={previousPage}>Back</Button> <Button primary on:click={previousPage}>Back</Button>
{/if} {/if}
{#if rows.length === pageSize} {#if nextBookmark != null}
<Button primary on:click={nextPage}>Next</Button> <Button primary on:click={nextPage}>Next</Button>
{/if} {/if}
</div> </div>