I found the bug. You can read my explanation in the first comment below.
When I search a previously serialized index, having loaded it using lunr.Index.load()
, I receive a TypeError
(shown in detail below). The following are steps to reproduce this error:
First, I create an index, add a document to the index, and log the index to ensure it is working:
var index = lunr(function () { //create index
this.field('title')
this.ref('id')
})
index.add({id: 1, title: 'apple' }) //add a document to index
console.log(index) //log index to demonstrate proper functionality
The following is the result of the console.log(index)
. As you see, everything is working correctly:
{ _fields: [ { name: 'title', boost: 1 } ],
_ref: 'id',
pipeline: { _stack: [ [Object], [Object] ] },
documentStore: { store: { '1': [Object] }, length: 1 },
tokenStore: { root: { docs: {}, a: [Object] }, length: 1 },
corpusTokens: { length: 1, elements: [ 'appl' ] } }
I then serialize the index and store it in my database:
user.index = index.toJSON() //serialise index and store it in the database
user.save() //save changes to database
Later, I load the previously serialised index and log the index to ensure it is working:
index = lunr.Index.load(user.index) //load previously serialised index from database
console.log(index) //log index to demonstrate proper functionality
The following is the result of the console.log(index)
. As you see, everything is working correctly and is identical to before:
{ _fields: [ { name: 'title', boost: 1 } ],
_ref: 'id',
pipeline: { _stack: [ [Object], [Object] ] },
documentStore: { store: { '1': [Object] }, length: 1 },
tokenStore: { root: { docs: {}, a: [Object] }, length: 1 },
corpusTokens: { length: 1, elements: [ 'appl' ] } }
Again, I will add a document to the index and log the index to ensure it is working after having loaded the previously serialized index:
index.add({id: 2, title: 'banana' }) //add a second document to index
console.log(index) //log index to demonstrate proper functionality
The following is the result of the console.log(index)
. As you see, everything is still working correctly:
{ _fields: [ { name: 'title', boost: 1 } ],
_ref: 'id',
pipeline: { _stack: [ [Object], [Object] ] },
documentStore: { store: { '1': [Object], '2': [Object] }, length: 2 },
tokenStore: { root: { docs: {}, a: [Object], b: [Object] }, length: 2 },
corpusTokens: { length: 2, elements: [ 'appl', 'banana' ] } }
Here is the problem. I will now attempt to search the index for a document that was added before serializing the index ({id: 1, title: 'apple' }
):
index.search('ap') //attempt to search index for document added before serialising index
This is there error I receive:
TypeError: Cannot read property '0' of undefined
at lunr.TokenStore.getNode (/home/danny/node_modules/lunr/lunr.js:1467:18)
at lunr.TokenStore.get (/home/danny/node_modules/lunr/lunr.js:1491:15)
at lunr.Index.documentVector (/home/danny/node_modules/lunr/lunr.js:908:30)
at null.<anonymous> (/home/danny/node_modules/lunr/lunr.js:880:61)
at Array.map (native)
at lunr.SortedSet.map (/home/danny/node_modules/lunr/lunr.js:453:24)
at lunr.Index.search (/home/danny/node_modules/lunr/lunr.js:879:6)
This is the code in its entirety:
var index = lunr(function () { //create index
this.field('title')
this.ref('id')
})
index.add({id: 1, title: 'apple' }) //add a document to index
console.log(index) //log index to demonstrate proper functionality
user.index = index.toJSON() //serialise index and store it to the database
user.save() //save changes to database
index = lunr.Index.load(user.index) //load previously serialised index from database
console.log(index) //log index to demonstrate proper functionality
index.add({id: 2, title: 'banana' }) //add a second document to index
console.log(index) //log index to demonstrate proper functionality
index.search('ap') //attempt to search index for document added before serialising index
Note: If, at the final line, I searched the index for 'ba'
, it would correctly return {id: 2, title: 'banana' }
, which was added after loading the index. Also, if I pass a query that normally would not return any result, such as 'da'
, it would correctly not return anything, without error.
Thank you very much.
I found the bug. You can read my explanation in the first comment below.