Indexing Typescript Todo Entities with Lunr

Ole Ersoy
2 min readMay 3, 2022
Image by Chil Vera from Pixabay

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!!"
}
]

Demo

--

--