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>

 检索结果也是秒出。

 

posted @ 2024-12-06 09:06  carol2014  阅读(135)  评论(0编辑  收藏  举报