Skip to content
This repository has been archived by the owner on Jun 22, 2023. It is now read-only.

Commit

Permalink
feat(search): improve the search algorithm
Browse files Browse the repository at this point in the history
The current search algorithm needs a few characters in order to find something. This is because it is only using a fuzzy search. This PR adds a second search pass using the OR operator.
  • Loading branch information
ChristiaanScheermeijer committed Nov 10, 2020
1 parent e72e51b commit d638f2c
Showing 1 changed file with 26 additions and 16 deletions.
42 changes: 26 additions & 16 deletions src/queries/SearchQuery.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class SearchQuery {
*/
get query () {
return [
`CALL db.index.fulltext.queryNodes("metadataSearchFields", "${this._generateIndexQueryClause(this._generateSubStringClause())}")`,
`CALL db.index.fulltext.queryNodes("metadataSearchFields", "${this._generateQueryClause()}")`,
`YIELD \`node\`, \`score\``,
this._generateTypeClause(),
`RETURN node { .*, FRAGMENT_TYPE: HEAD(labels(node)), _searchScore: \`score\` }`,
Expand All @@ -27,43 +27,53 @@ class SearchQuery {
}

/**
* @param field
* @returns {string}
* @private
*/
_generateSubStringClause () {
_generateFieldSubStringClause (field) {
// empty substring
if (!this.params.substring) {
return '/.*/'
return `${field}:/.*/`
}

const subString = this.params.substring.replace(/[^A-Za-z0-9]/g, '')

// prepare search substring
let subStringClause = `${this.params.substring.replace(/[^A-Za-z0-9]/g, ' ')}~`
return `${field}:'/${subString}.*/' OR ${field}:'${subString}~'`
}

if (subStringClause.includes(' ')) {
subStringClause = `'${subStringClause}'`
/**
* @returns {string}
* @private
*/
_generateSubStringClause () {
// empty substring
if (!this.params.substring) {
return `/.*/`
}

return subStringClause
const subString = this.params.substring.replace(/[^A-Za-z0-9\s]/g, '')

// prepare search substring
return `'/${subString}.*/' OR '${subString}~'`
}

/**
* @param subStringClause
* @returns {*|string}
* @private
*/
_generateIndexQueryClause (subStringClause) {
_generateQueryClause () {
// if only a subset of fields need to be evaluated: build query clause for [substring]~ on all eligible fields
let indexQueryClause = subStringClause
if (this.doEvaluateFieldSubset) {
const fieldNames = this.doEvaluateFieldSubset ? this.params.onFields : this.resolveInfo.schema._typeMap.SearchableMetadataFields._values.map(field => { return field.name })
let queryClauses = []
fieldNames.map(field => {
queryClauses.push(`${field}:${subStringClause}`)
})
indexQueryClause = queryClauses.join(' OR ')

return fieldNames
.map(field => this._generateFieldSubStringClause(field))
.join(' OR ')
}

return indexQueryClause
return this._generateSubStringClause()
}

/**
Expand Down

0 comments on commit d638f2c

Please sign in to comment.