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:
parent
a5fd8d0e33
commit
659874c9ee
|
@ -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,23 +264,29 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
// make all strings a starts with operation rather than pure equality
|
let searchString
|
||||||
for (const [key, queryVal] of Object.entries(query)) {
|
if (ctx.query.raw && ctx.query.raw !== "") {
|
||||||
if (typeof queryVal === "string") {
|
searchString = queryBuilder.complete(query["RAW"])
|
||||||
queryBuilder.addString(key, queryVal)
|
} else {
|
||||||
} else {
|
// make all strings a starts with operation rather than pure equality
|
||||||
queryBuilder.addEqual(key, queryVal)
|
for (const [key, queryVal] of Object.entries(query)) {
|
||||||
|
if (typeof queryVal === "string") {
|
||||||
|
queryBuilder.addString(key, queryVal)
|
||||||
|
} else {
|
||||||
|
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) {
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
|
@ -1,23 +1,25 @@
|
||||||
|
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 += `&limit=${limit}`
|
||||||
|
if (!excludeDocs) {
|
||||||
url += "&include_docs=true"
|
url += "&include_docs=true"
|
||||||
}
|
}
|
||||||
if (limit) {
|
|
||||||
url += `&limit=${limit}`
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
bookmark = lastBookmark
|
if (lastBookmark !== bookmark) {
|
||||||
|
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>
|
||||||
|
|
Loading…
Reference in New Issue