diff --git a/src/search/indexer.js b/src/search/indexer.js index 8250b649af80..f5ae12fab8f4 100644 --- a/src/search/indexer.js +++ b/src/search/indexer.js @@ -12,7 +12,8 @@ export type Doc = { tokenizedBox: string, functionNames: string, tokenizedFunctionNames: string, - description: string + description: string, + minDescription: string }; let localIndex; @@ -21,6 +22,15 @@ function tokenizeStr(str: string): string { return str.trim().split(/(?=[A-Z])/).join(' ').toLowerCase().split(/ |_|-/).join(' '); } +/** + * returns the first sentence of the description. + * @param {string} desc + * @return {string} + */ +function minimizeDescription(desc: string = ''): string { + return desc.split(/\.|;/)[0]; // split by a dot or a semicolon +} + function prepareDoc(docs: Object, component: Component): Doc { const name = component.name; const box = component.box; @@ -28,12 +38,14 @@ function prepareDoc(docs: Object, component: Component): Doc { return { id: `${box}_${name}`, name, - tokenizedName: tokenizeStr(name), box, + tokenizedNameExtra: tokenizeStr(name), // TODO: remove it when possible + tokenizedName: tokenizeStr(name), tokenizedBox: tokenizeStr(box), functionNames, tokenizedFunctionNames: tokenizeStr(functionNames), - description: docs.map(doc => doc.description).join(' ') + description: docs.map(doc => doc.description).join(' '), + minDescription: docs.map(doc => minimizeDescription(doc.description)).join(' ') }; } diff --git a/src/search/searcher.js b/src/search/searcher.js index c41cc59e63d1..b7f3468e9057 100644 --- a/src/search/searcher.js +++ b/src/search/searcher.js @@ -3,6 +3,16 @@ import serverlessIndex from './serverless-index'; import indexer from './indexer'; import type Doc from './indexer'; +const boost = { + box: 3, + tokenizedBox: 2, + name: 5, + tokenizedName: 4, + functionNames: 2, + tokenizedFunctionNames: 2, + minDescription: 1 +}; + function totalHits(index: Promise, query: string) { return new Promise((resolve, reject) => { return index.then((indexInstance) => { @@ -41,23 +51,26 @@ function formatSearchResult(doc: Doc): string { return `> ${doc.box}/${doc.name}`; } -function queryItem(field, query, boost = 1) { - return { - AND: { [field]: query.toLowerCase().split(' ') }, - BOOST: boost +function queryItem(field, queryStr): Object { + const query = { + AND: { [field]: queryStr.toLowerCase().split(' ') }, + BOOST: boost[field], + NOT: {} }; + + return query; } -function buildQuery(queryStr: string) { +function buildQuery(queryStr: string): Array { const tokenizedQuery = indexer.tokenizeStr(queryStr); const query = []; - query.push(queryItem('box', queryStr, 4)); - query.push(queryItem('tokenizedBox', queryStr, 3)); - query.push(queryItem('name', queryStr, 4)); - query.push(queryItem('tokenizedName', tokenizedQuery, 3)); - query.push(queryItem('functionNames', queryStr, 3)); - query.push(queryItem('tokenizedFunctionNames', tokenizedQuery, 2)); - query.push(queryItem('description', queryStr)); + query.push(queryItem('box', queryStr)); + query.push(queryItem('tokenizedBox', queryStr)); + query.push(queryItem('name', queryStr)); + query.push(queryItem('tokenizedName', tokenizedQuery)); + query.push(queryItem('functionNames', queryStr)); + query.push(queryItem('tokenizedFunctionNames', tokenizedQuery)); + query.push(queryItem('minDescription', queryStr)); return query; } diff --git a/src/search/serverless-index.js b/src/search/serverless-index.js index 0f9910418763..bd50fd6763fc 100644 --- a/src/search/serverless-index.js +++ b/src/search/serverless-index.js @@ -19,7 +19,8 @@ function deleteDb(scopePath: string) { function initializeIndex(scopePath: string): Promise { const indexOptions = { indexPath: getIndexPath(scopePath), - logLevel + logLevel, + stopwords: [] }; if (!initializeIndex.index) { // static var to make sure the index is not instantiated twice