首页 > 其他分享 >js前端搜索组件flexsearch使用

js前端搜索组件flexsearch使用

时间:2024-12-05 17:23:08浏览次数:5  
标签:search last movie js add str text 组件 flexsearch

说明文档往往有搜索框,可以根据关键字检索文档内容。我有时疑惑这种检索是后端DB检索还是其它的呢?

拿bootstrap-table的说明文档看下:是由algolia提供的检索服务api

那普通的内容页面有没有可能实现前端检索呢?

查资料,找到了flexsearch这个js检索组件,试用下:

说明及常用方法

有三种类型的索引:
Index是一个扁平的高性能索引,用于存储id内容对。
Worker/WorkerIndex也是一个平面索引,它存储id内容对,但在后台作为专用工作线程运行。
Document是一个多字段索引,可以存储复杂的JSON文档(也可能存在worker索引)。

worker继承自Index类型,不继承自Document类型。因此,WorkerIndex的工作原理基本上类似于标准的FlexSearch索引。文档中的Worker支持需要在创建过程中通过传递适当的选项来启用{Worker:true}。
在Worker索引上调用的每个方法都被视为异步方法。您将返回一个Promise,或者您也可以提供一个回调函数作为最后一个参数。 

查看代码
     const index = new FlexSearch.Index();
    const document = new FlexSearch.Document();
    const worker = new FlexSearch.Worker();

    index.add(id, text);
    index.search(text);
    index.search(text, limit);
    index.search(text, options);
    index.search(text, limit, options);
    index.search(options);

    document.add(doc);
    document.add(id, doc);
    document.search(text);
    document.search(text, limit);
    document.search(text, options);
    document.search(text, limit, options);
    document.search(options);

    worker.add(id, text);
    worker.search(text);
    worker.search(text, limit);
    worker.search(text, options);
    worker.search(text, limit, options);
    worker.search(text, limit, options, callback);
    worker.search(options);

简单使用

<script src="../plugins/flexsearch.bundle.min.js"></script>
<script>
  //  英文检索
  const movie_en = new FlexSearch.Index();
  movie_en.add(1, "明天");
  movie_en.add(2, "this today");
  movie_en.add(3, "tomorow");
  movie_en.add(4, "hello world");

  movie_en.append(2, "some appended content");
  movie_en.update(3, "tomorow is anthor day");
  movie_en.remove(4);

   //不支持英文单词中部分字母的模糊检索和中文检索
  const arr = ["today", "天", "row", "content", "world"];
  for (let str of arr) {
    console.log(str, movie_en.search(str));
  }
  console.log("-----------------");
</script>

中文检索

查看代码
  // 中文检索,指定分词器,不支持英文检索
  const movie_cn = FlexSearch.Index({
    encode: (str) => str.replace(/[\x00-\x7F]/g, "").split(""),
  });
  movie_cn.add(1, "明天是新的一天,出去游玩");
  movie_cn.add(2, "西游记");
  movie_cn.add(3, "红楼梦");
  movie_cn.add(4, "hello world");

  const arr1 = ["天", "游记", "world"];
  for (let str of arr1) {
    console.log(str, movie_cn.search(str));
  }
  console.log("-----------------");

 

 中英文混合检索

分词算法来自于  https://liaoxuefeng.com/blogs/all/2024-01-05-js-full-text-search/index.html 

查看代码
  const ALPHABETS = [
    [0x30, 0x39], // 0-9
    [0x41, 0x5a], // A-Z
    [0x61, 0x7a], // a-z
    [0xc0, 0x2af], // part of Latin-1 supplement / Latin extended A/B / IPA
    [0x370, 0x52f], // Greek / Cyrillic / Cyrillic supplement
  ];

  const SINGLE_CHARS = [
    [0xe00, 0x0e5b], // Thai
    [0x3040, 0x309f], // Hiragana
    [0x4e00, 0x9fff], // CJK
    [0xac00, 0xd7af], // Hangul syllables
  ];

  function isAlphabet(n) {
    for (let range of ALPHABETS) {
      if (n >= range[0] && n <= range[1]) {
        return true;
      }
    }
    return false;
  }

  function isSingleChar(n) {
    for (let range of SINGLE_CHARS) {
      if (n >= range[0] && n <= range[1]) {
        return true;
      }
    }
    return false;
  }

  function tokenizer(str) {
    const length = str.length;
    const tokens = [];
    let last = "";
    for (let i = 0; i < length; i++) {
      let code = str.charCodeAt(i);
      if (isSingleChar(code)) {
        if (last) {
          if (last.length > 1) {
            tokens.push(last.toLowerCase());
          }
          last = "";
        }
        tokens.push(str[i]);
      } else if (isAlphabet(code)) {
        last = last + str[i];
      } else {
        if (last) {
          if (last.length > 1) {
            tokens.push(last.toLowerCase());
          }
          last = "";
        }
      }
    }
    if (last) {
      if (last.length > 1) {
        tokens.push(last.toLowerCase());
      }
      last = "";
    }
    //console.log(str, tokens);
    return tokens;
  }

  const movie = new FlexSearch.Index({
    encode: tokenizer,
  });
  movie.add(1, "明天,又是新的一天");
  movie.add(2, "The Lock Artist");
  movie.add(3, "明天,The Lock Artist");
  movie.add(4, "天空很蓝");
  const arr2 = ["天", "明天", "artist"];
  for (let str of arr2) {
    console.log(str, movie.search(str));
  }

 

 使用全唐诗测试

  

查看代码
 <?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/flexsearch.bundle.min.js"></script>
<script>
  const word = {
    ALPHABETS: [
      [0x30, 0x39], // 0-9
      [0x41, 0x5a], // A-Z
      [0x61, 0x7a], // a-z
      [0xc0, 0x2af], // part of Latin-1 supplement / Latin extended A/B / IPA
      [0x370, 0x52f], // Greek / Cyrillic / Cyrillic supplement
    ],
    SINGLE_CHARS: [
      [0xe00, 0x0e5b], // Thai
      [0x3040, 0x309f], // Hiragana
      [0x4e00, 0x9fff], // CJK
      [0xac00, 0xd7af], // Hangul syllables
    ],
    isAlphabet: function(n) {
      for (let range of this.ALPHABETS) {
        if (n >= range[0] && n <= range[1]) {
          return true;
        }
      }
      return false;
    },
    isSingleChar: function(n) {
      for (let range of this.SINGLE_CHARS) {
        if (n >= range[0] && n <= range[1]) {
          return true;
        }
      }
      return false;
    }
  }

  function tokenizer(str) {
    const length = str.length;
    const tokens = [];
    let last = "";
    for (let i = 0; i < length; i++) {
      let code = str.charCodeAt(i);
      if (word.isSingleChar(code)) {
        if (last) {
          if (last.length > 1) {
            tokens.push(last.toLowerCase());
          }
          last = "";
        }
        tokens.push(str[i]);
      } else if (word.isAlphabet(code)) {
        last = last + str[i];
      } else {
        if (last) {
          if (last.length > 1) {
            tokens.push(last.toLowerCase());
          }
          last = "";
        }
      }
    }
    if (last) {
      if (last.length > 1) {
        tokens.push(last.toLowerCase());
      }
      last = "";
    }
    return tokens;
  }

  let documents = JSON.parse('<?= json_encode($data) ?>');
  const doc_index = FlexSearch.Index({
    encode: tokenizer,
  });
  for (let i in documents) {
    doc_index.add(parseInt(i), documents[i])
  }
</script>
<script>
  function search() {
    return {
      keyword: "",
      items: documents,
      num: 0,
      get filteredItems() {
        res = doc_index.search(this.keyword);
        this.num = res.length;
        return this.items.filter((item, i) => {
          return res.indexOf(i) >= 0
        });
      },
    };
  }
</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>

前端检索的速度很快。

标签:search,last,movie,js,add,str,text,组件,flexsearch
From: https://www.cnblogs.com/caroline2016/p/18588999

相关文章

  • 纯js可定制的跨浏览器日期时间选择器插件
    Rome是一款纯js可定制的跨浏览器日期时间选择器插件。该日期时间选择器不依赖于jquery,但它依赖于moments.js。可以通过CSS文件来自定义该日期时间选择器的外观样式。在线预览 下载  安装可以通过Bower或nmp来安装该日期时间选择器插件。npminstall--saveromebower......
  • 使用printJs实现打印效果
    一、需求需要实现部分页面的内容打印;页面内容为表单,表单中还包括了表格。使用了 a-form、a-row、a-table 相关组件二、实现方法1、安装print-js npminstall--saveprint-js 2、给需要打印的部分设置一个id例如:我需要打印的是一整个表单内容,就再form表单上面设置id(此i......
  • 【WEB开发.js】HTTP请求和相应报文的头字段:Content-Type (巨巨巨巨详细好懂的举例详解)
    Content-Type是HTTP请求和响应报文中的头字段之一,用于指定发送的数据类型(MIME类型)。它告诉服务器或客户端数据的格式,方便接收方正确解析和处理内容。例如,在发送JSON数据时,会指定Content-Type:application/json;而发送HTML页面时,则会指定Content-Type:text/html。......
  • 求助——AssertionError: Attribute pipeline is missing from configuration.json.
    我在本地运行Sunsimiao大模型的时候遇到了“AssertionError:Attributepipelineismissingfromconfiguration.json.”的问题。在网上找了很多问题都没有解决,求助一下广大网友。有什么好的解决方法吗?本地环境如上所示,不知是哪里出现了问题!!!!......
  • Nuxt.js 应用中的 beforeResponse 事件钩子
    title:Nuxt.js应用中的beforeResponse事件钩子date:2024/12/5updated:2024/12/5author:cmdragonexcerpt:在Web开发中,处理响应是一个至关重要的环节。Nuxt.js提供的beforeResponse钩子允许开发者在发送响应之前对结果进行修改或处理。这一机制非常有助于确保返......
  • vs2012 cmake dll工程 调试dll launch.vs.json 附加到进程
    在VisualStudio中,当你有一个DLL项目并且想要附加调试这个DLL时,你需要指定宿主应用程序(在这个例子中是bt.exe),因为DLL本身不是独立可执行的。以下是如何配置launch.vs.json文件以便附加到bt.exe并调试limit-ml-model.dll的步骤:确定宿主应用程序(bt.exe)的路径:你需要知道bt.exe的......
  • node.js毕设基于微信小程序的同城快运系统小程序端程序+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于同城快运系统的研究,现有研究主要以传统的物流管理系统为主,专门针对基于微信小程序的同城快运系统的研究较少。在国内外,物流行业发展迅速,同城快递的......
  • node.js毕设勤工助学管理系统 程序+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于勤工助学管理系统的研究,现有研究主要集中在高校管理系统的一般性研究上,专门针对勤工助学管理系统的研究较少。在国内外,高校管理系统的发展已经较为......
  • RTSP播放器EasyPlayer.js报错The play() request was interrupted because video-only
    随着技术的发展,越来越多的H5流媒体播放器开始支持H.265编码格式。例如,EasyPlayer.jsH5播放器能够支持H.264、H.265等多种音视频编码格式,这使得播放器能够适应不同的视频内容和网络环境。那么为什么会出现Theplay()requestwasinterruptedbecausevideo-onlybackgroundmed......
  • 如何使用js去调用vscode-js-debugger的方法去调试网页?
    ......