Indexing Typescript Todo Entities with Lunr
Scenario
We have Todo
entities defined using this interface:
interface Todo {
gid?: string;
id?: string;
complete: boolean;
title: string;
}
And we have a few instances of it:
const TODO_ID_1 = '1';
const TODO_ID_2 = '2';const TODO1: Todo = {
id: TODO_ID_1,
complete: false,
title: 'You complete me!'
};const TODO2: Todo = {
id: TODO_ID_2,
complete: true,
title: 'You completed me!'
};let todos: Todo[] = [TODO1, TODO2];
And we want to index these using Lunr.js
so that we can search for Todo
entities.
Approach
First we need to add lunr
and @types/lunr
to our Stackblitz.
Then create the index like this by passing a callback function to lunr
that will index the Todo
fields complete
and title
.
function initializeSearchIndex(todos: Todo[]): lunr.Index {
const idx: lunr.Index = lunr(function () {
this.field('complete');
this.field('title');
todos.forEach((todo) => {
this.add(todo);
});
});
return idx;
}
Once we have the index we can use it to search for Todo
instances.
const idx = initializeSearchIndex(todos);
const idxResult: lunr.Index.Result[] = idx.search('false');
And if we console.log
the idxResult
we see that it contains the incomplete Todo
instance reference with ref
id
1
:
[
{
"ref": "1",
"score": 0.693,
"matchData": {
"metadata": {
"fals": {
"complete": {}
}
}
}
}
]
So we need to map this result using our todos
array.
function search(query: string) {
const results = idx.search(query);
return results.map((result) => {
return todos.find((todo) => result.ref === todo.id);
});
}
And now we can search for our Todo
instances.
const searchResult = search('false');
//console.log(searchResult);
Now our search result contains the Todo
instance with complete
set too false
.
[
{
"id": "1",
"complete": false,
"title": "Firefly Semantics Slice Rocks!!"
}
]