fuse.js
中对于索引
能力的说明和示例相对简单。主要使用到3个函数:
Fuse.createIndex()
Fuse.parseIndex()
FuseIndex.prototype.toJSON()
具体示例也粘贴过来
javascript
const books = [
{
"title": "Old Man's War",
"author": {
"firstName": "John",
"lastName": "Scalzi"
}
},
{
"title": "The Lock Artist",
"author": {
"firstName": "Steve",
"lastName": "Hamilton"
}
}
/*...*/
]
// 示例 Part1
// 创建 `FuseIndex` 索引对象
const myIndex = Fuse.createIndex(['title', 'author.firstName'], books)
// 调用 `toJSON()` 方法得到索引对象的 JSON 对象,并将其写到 `fuse-index.json` 文件中
fs.writeFile('fuse-index.json', JSON.stringify(myIndex.toJSON()))
// 示例 Part2
// 从文件 `fuse-index.json` 中读取之前存储的 JSON 对象
const fuseIndex = await require('fuse-index.json')
// 将 JSON 对象重新解析生成一个 `FuseIndex` 索引对象
const myIndex = Fuse.parseIndex(fuseIndex)
// 使用索引对象创建
const fuse = new Fuse(books, options, myIndex)
示例简单,但是在业务中使用场景会很复杂,比如:
- 需要搜索的数据很多,也就是
books.length
可能会比较大,有时不可能一次性读取全量books
数据。 books
的数据是异步读取的,比如通过请求接口、读取本地文件的方式获取。
如果 books 数据不可能全部获取,那创建 Fuse
实例时是否可以不传入 books
?
javascript
const fuse = new Fuse([], options, myIndex)
用该实例搜索后发现返回结果中缺少 item
,也就是对应的 book
数据,但搜索结果中的匹配信息仍旧存在。
javascript
// 搜索 'Lock' 关键字并获得结果
const result = fuse.search('Lock')
result
对下如下:
JSON
[
{
"refIndex": 1,
"matches": [
{ "indices": [[4, 7]], "value": "The Lock Artist", "key": "title" }
],
"score": 0.15609486447437038
}
]
对比正常情况下的搜索结果如下:
JSON
[
{
"item": {
"title": "The Lock Artist",
"author": { "firstName": "Steve", "lastName": "Hamilton" }
},
"refIndex": 1,
"matches": [
{ "indices": [[4, 7]], "value": "The Lock Artist", "key": "title" }
],
"score": 0.15609486447437038
}
]
此时有一个疑问,如果不是传入空数组,而是传入一个和之前毫不相关的 books
数据,会发生什么? 尝试传入 books.reverse()
:
javascript
const fuse = new Fuse(books.reverse(), options, myIndex)
此时再搜索的话,得到结果:
JSON
[
{
"item": {
"title": "Old Man's War",
"author": { "firstName": "John", "lastName": "Scalzi" }
},
"refIndex": 1,
"matches": [
{ "indices": [[4, 7]], "value": "The Lock Artist", "key": "title" }
],
"score": 0.15609486447437038
}
]
其实可以猜测,索引对象是通过数组下标的形式关联对应的 book
数据,看起来可能返回结果中的 refIndex
就是对应的下标。
在此基础上,我们可以来解决之前遇到的问题:在创建 Fuse
实例时,无需传入 books
数据(或者只传入类似于 [{ id: '123' }, { id: '456' }]
这种数据),而只需要索引文件,仍旧可以完成搜索,并且使用 refIndex
或者其他搜索结果中的数据来进一步获取更详细的数据。