diff --git a/src/MiniSearch.test.js b/src/MiniSearch.test.js index a2c48162..fc01805b 100644 --- a/src/MiniSearch.test.js +++ b/src/MiniSearch.test.js @@ -1349,6 +1349,10 @@ describe('MiniSearch', () => { ['vita', 'nova'], ['vita'] ]) + expect(results.map(({ queryTerms }) => queryTerms)).toEqual([ + ['vita', 'nova'], + ['vita'] + ]) }) it('reports correct info when combining terms with AND', () => { @@ -1359,6 +1363,9 @@ describe('MiniSearch', () => { expect(results.map(({ terms }) => terms)).toEqual([ ['vita', 'nova'] ]) + expect(results.map(({ queryTerms }) => queryTerms)).toEqual([ + ['vita', 'nova'] + ]) }) it('reports correct info for fuzzy and prefix queries', () => { @@ -1371,6 +1378,10 @@ describe('MiniSearch', () => { ['vita', 'nova'], ['vita'] ]) + expect(results.map(({ queryTerms }) => queryTerms)).toEqual([ + ['vi', 'nuova'], + ['vi'] + ]) }) it('reports correct info for many fuzzy and prefix queries', () => { @@ -1385,6 +1396,11 @@ describe('MiniSearch', () => { ['vita', 'mezzo', 'del'], ['del'] ]) + expect(results.map(({ queryTerms }) => queryTerms)).toEqual([ + ['vi', 'nuova', 'm', 'de'], + ['vi', 'm', 'de'], + ['de'] + ]) }) it('passes only the query to tokenize', () => { diff --git a/src/MiniSearch.ts b/src/MiniSearch.ts index 49633520..6ecbfff7 100644 --- a/src/MiniSearch.ts +++ b/src/MiniSearch.ts @@ -288,10 +288,17 @@ export type SearchResult = { id: any, /** - * List of terms that matched + * List of document terms that matched. For example, if a prefix search for + * `"moto"` matches `"motorcycle"`, `terms` will contain `"motorcycle"`. */ terms: string[], + /** + * List of query terms that matched. For example, if a prefix search for + * `"moto"` matches `"motorcycle"`, `queryTerms` will contain `"moto"`. + */ + queryTerms: string[], + /** * Score of the search results */ @@ -1229,14 +1236,17 @@ export default class MiniSearch { const results = [] for (const [docId, { score, terms, match }] of rawResults) { - // Final score takes into account the number of matching QUERY terms. - // The end user will only receive the MATCHED terms. + // terms are the matched query terms, which will be returned to the user + // as queryTerms. The quality is calculated based on them, as opposed to + // the matched terms in the document (which can be different due to + // prefix and fuzzy match) const quality = terms.length || 1 const result = { id: this._documentIds.get(docId), score: score * quality, terms: Object.keys(match), + queryTerms: terms, match }