js前端模糊搜索组件fuse.js使用
前端检索组件除了flexsearch.js,还可以使用fuse.js。fuse.js支持中文检索,且较flexsearch.js提供了模糊检索、匹配度分数以及权重检索等。
简单使用
<script src="../plugins/fuse/fuse.min.js"></script>
<script>
{
const list = ["Old Man's War", "The Lock Artist", "红楼梦", "西游记"];
const options = {
includeScore: true,
};
const fuse = new Fuse(list, options);
const arr = ["od man", "梦"];
for (let str of arr) {
console.log(str, fuse.search(str));
}
console.log("-----------------");
// od man [{item: "Old Man's War", refIndex: 0, score: 0.3556368284111493}]
// 梦 {item: '红楼梦', refIndex: 2, score: 0.02}
}
{
const list = [
{
title: "Old Man's War",
author: "John Scalzi",
tags: ["fiction"],
},
{
title: "The Lock Artist",
author: "Steve",
tags: ["thriller"],
},
{
title: "红楼梦",
author: "曹雪芹",
tags: ["小说", "古言"],
},
{
title: "西游记",
author: "吴承恩",
tags: ["小说", "古言"],
},
];
const options = {
includeScore: true,
keys: ["author", "tags"], //检索author和tags
};
const fuse = new Fuse(list, options);
const arr = ["tion", "芹"];
for (let str of arr) {
console.log(str, fuse.search(str));
}
console.log("-----------------");
// tion [item:{title: "Old Man's War", author: 'John Scalzi',tags:['fiction'],refIndex:0,score: 0.03]
// 芹 [item:{title: "红楼梦", author: '曹雪芹',tags:["小说", "古言"],refIndex:2,score: 0.02]
}
//嵌套检索
{
const list = [
{
title: "Old Man's War",
author: {
name: "John Scalzi",
tags: [
{
value: "American",
},
],
},
},
{
title: "The Lock Artist",
author: {
name: "Steve Hamilton",
tags: [
{
value: "English",
},
],
},
},
];
const options = {
includeScore: true,
keys: ["author.tags.value"],
};
const fuse = new Fuse(list, options);
const result = fuse.search("engsh");
console.log(result);
// [{item: {author: {name: "Steve Hamilton",tags: {value: 'English'}},title: "The Lock Artist"},refIndex: 1,score: 0.4}]
const options2 = {
includeScore: true,
keys: [["author", "tags", "value"]],
};
const fuse2 = new Fuse(list, options2);
const result2 = fuse2.search("engsh");
console.log(result2);
//结果同上
const options3 = {
includeScore: true,
keys: [
{ name: "title", getFn: (book) => book.title },
{ name: "authorName", getFn: (book) => book.author.name },
],
};
const fuse3 = new Fuse(list, options3);
const result3 = fuse3.search({ authorName: "Steve" });
console.log(result3);
console.log("-----------------");
//结果同上
}
</script>
指定权重检索
查看代码
//带权重的检索
{
const list = [
{
title: "Old Man's War fiction",
author: "John X",
tags: ["war"],
},
{
title: "Right Ho Jeeves",
author: "P.D. Mans",
tags: ["fiction", "war"],
},
];
const options = {
includeScore: true,
keys: [
{
name: "title",
weight: 0.3,
},
{
name: "author",
weight: 0.7,
},
],
};
const fuse = new Fuse(list, options);
const result = fuse.search("Man");
console.log(result);
// [{item:{title: 'Right Ho Jeeves', author: 'P.D. Mans', tags: ['fiction', 'war']},refIndex:1,score:0.2270493459280866},
// {item:{title: 'Old Man's War fiction', author: 'John X', tags: ["war"]},refIndex:0,score:0.6170338627200096} ]
const fuse2 = new Fuse(list, {
keys: [
"title", // 默认权重1
{
name: "author",
weight: 2,
},
],
});
const result2 = fuse2.search("Man");
console.log(result2);
console.log("-----------------");
//结果同上,不带score
}
//扩展检索
{
const list = [
{
title: "Old Man's War",
author: "John Scalzi",
},
{
title: "The Lock Artist",
author: "Steve",
},
{
title: "Artist for Life",
author: "Michelangelo",
},
];
const options = {
includeScore: true,
useExtendedSearch: true,
keys: ["title"],
};
const fuse = new Fuse(list, options);
const result = fuse.search("'Man 'Old | Artist$"); //检索包含 Man和Old 或者以Artist结尾的
console.log(result);
// [{item:{title: 'Old Man's War', author: 'John Scalzi'},refIndex:0,score:9.287439764962262e-10},
// {item:{title: 'The Lock Artist', author: 'Steve'},refIndex:1,score:9.287439764962262e-10} ]
}
使用全唐诗测试
查看代码
<?php
try {
$dsn = "mysql:host=127.0.0.1;port=3306;dbname=test;charset=utf8";
$user = "root";
$password = "";
$pdo = new PDO($dsn, $user, $password, [PDO::ATTR_PERSISTENT => true]);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $error) {
die('connect error');
}
$sql = "select title,author,content from tb_chinese_poems";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$data = [];
while ($row = $stmt->fetch()) {
$data[] = str_replace(["\n", "\r"], '', $row['title'] . ' - ' . $row['author'] . ' - ' . $row['content']);
}
?>
<script type="text/javascript" src="../plugins/alpine.min.js"></script>
<script src="../plugins/fuse/fuse.min.js"></script>
<script>
let documents = JSON.parse('<?= json_encode($data) ?>');
const fuse = new Fuse(documents, {
includeScore: true
});
</script>
<script>
function search() {
return {
keyword: "",
items: documents,
num: 0,
get filteredItems() {
const res = fuse.search(this.keyword);
res.sort((a, b) => {
return a.score - b.score
})
this.num = res.length;
return res.map((item, i) => item.item);
},
};
}
</script>
<div x-data="search()">
<input x-model="keyword" placeholder="Search..." />
<p>共检索到<span x-text="num"></span>条</p>
<ul>
<template x-for="(item,index) in filteredItems" :key="index">
<li x-text="item"></li>
</template>
</ul>
</div>
检索结果也是秒出。