Fix in-doc search not working when stopword is in title (#1)

* Trying to reproduce stop-word error but couldn't

* Update and add appropriate test case for stop-word testing

* Implement fix for stopword in title, add unit test case

Signed-off-by: Seow Wen Han <wseow@seekasia.com>
This commit is contained in:
Seow Wen Han
2022-08-23 13:36:57 +08:00
committed by Seow Wen Han
parent 07c0d9ff6f
commit 5e14cea98b
2 changed files with 130 additions and 4 deletions
@@ -1092,3 +1092,123 @@ describe('parseHighlightFields', () => {
});
});
});
describe('stopword testing', () => {
let testLunrSearchEngine: SearchEngine;
beforeEach(() => {
testLunrSearchEngine = new LunrSearchEngine({ logger: getVoidLogger() });
jest.clearAllMocks();
});
it('test with stopword in title', async () => {
const mockDocuments = [
{
title: 'a home',
text: 'mary had a little lamb at home',
location: 'test/location',
},
];
const indexer = await getActualIndexer(testLunrSearchEngine, 'test-index');
await TestPipeline.withSubject(indexer)
.withDocuments(mockDocuments)
.execute();
const mockedSearchResult = await testLunrSearchEngine.query({
term: 'mary',
filters: {
title: 'a home',
},
});
expect(mockedSearchResult).toMatchObject({
results: [
{
document: {
title: 'a home',
text: 'mary had a little lamb at home',
location: 'test/location',
},
rank: 1,
},
],
nextPageCursor: undefined,
});
});
it('test with stopword connected with dash', async () => {
const mockDocuments = [
{
title: 'a-home',
text: 'mary had a little lamb at home',
location: 'test/location',
},
];
const indexer = await getActualIndexer(testLunrSearchEngine, 'test-index');
await TestPipeline.withSubject(indexer)
.withDocuments(mockDocuments)
.execute();
const mockedSearchResult = await testLunrSearchEngine.query({
term: 'mary',
filters: {
title: 'a-home',
},
});
expect(mockedSearchResult).toMatchObject({
results: [
{
document: {
title: 'a-home',
text: 'mary had a little lamb at home',
location: 'test/location',
},
rank: 1,
},
],
nextPageCursor: undefined,
});
});
it('test with only stop word in title', async () => {
const mockDocuments = [
{
title: 'a',
text: 'mary had a little lamb at home',
location: 'test/location',
},
];
const indexer = await getActualIndexer(testLunrSearchEngine, 'test-index');
await TestPipeline.withSubject(indexer)
.withDocuments(mockDocuments)
.execute();
const mockedSearchResult = await testLunrSearchEngine.query({
term: 'mary',
filters: {
title: 'a',
},
});
expect(mockedSearchResult).toMatchObject({
results: [
{
document: {
title: 'a',
text: 'mary had a little lamb at home',
location: 'test/location',
},
rank: 1,
},
],
nextPageCursor: undefined,
});
});
});
@@ -114,10 +114,16 @@ export class LunrSearchEngine implements SearchEngine {
// Require that the given field has the given value
if (['string', 'number', 'boolean'].includes(typeof value)) {
q.term(lunr.tokenizer(value?.toString()), {
presence: lunr.Query.presence.REQUIRED,
fields: [field],
});
q.term(
lunr
.tokenizer(value?.toString())
.map(lunr.stopWordFilter)
.filter(element => element !== undefined),
{
presence: lunr.Query.presence.REQUIRED,
fields: [field],
},
);
} else if (Array.isArray(value)) {
// Illustrate how multi-value filters could work.
// But warn that Lurn supports this poorly.