Merge pull request #13297 from swenhan/master

Fix in-doc search no result when title has stopwords
This commit is contained in:
Emma Indal
2022-08-29 11:05:31 +02:00
committed by GitHub
3 changed files with 135 additions and 4 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-search-backend-node': patch
---
Fixed bug in LunrSearchEngine where stopwords in title is causing in-doc search not working
@@ -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.