Skip to content

搜索扩展

目前默认的搜索服务是基于开源项目 Lunr 实现的,从前端角度实现了对文章内容的搜索,但是在使用体验上,感觉不是特别好,大概有如下几个原因:

  • 社区的文章数量比较少,项目的 Commit 也停在了4年前;
  • 中文搜索的问题,虽然可以通过 lunr-languagesstemmerSupport 等库来实现中文分词搜索,但是分词效果和搜索结果上差强人意。
  • 当文件多了之后,本地构建的索引文件会比较大,导致加载速度变慢。

一、Orama

1.1创建索引

在后台里创建网站的索引,如下图:

这里 Presets 选项要选 Website, 然后点击按提示 部署 就好。待部署完成后,开始在自己的网站配置。

1.2 网站配置

1.2.1 SDK 配置

这里提供了两种配置方式,一种是通过 SDK 来实现,具体在 Usage 菜单中可以看到相关内容,如下:

1.2.2 UI components

推荐使用 UI components 来配置,这样可以使用 OramaCloud 提供的 UI components 来实现搜索,避免自己来实现搜索相关的UI:

最总效果图如下:

Orama 还提供来了 Chat 功能,这个功能可以让用户通过 Chat 来实现搜索,大家可以自行配置体验

1.3 项目配置

1.3.1 安装依赖:
Terminal window
pnpm add @orama/react-components
1.3.2 更新配置
src/components/Header.astro
<div class='absolute md:flex md:right-8 right-1/2 hidden'>
<Search category={category} client:only='react' />
<Search client:only='react' />
<ToggleTheme client:load />
</div>
1.3.3 创建 Orama 组件
src/components/OramaBox.tsx
import { OramaSearchBox } from '@orama/react-components';
import { useEffect, useState, type FC } from 'react';
const OramaBox: FC = () => {
const [theme, setThemeState] = useState<'light' | 'dark' | 'system'>('light');
useEffect(() => {
const observer = new MutationObserver(() => {
const isDark = document.documentElement.classList.contains('dark');
setThemeState(isDark ? 'dark' : 'light');
});
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
return () => {
observer.disconnect();
};
}, []);
return (
<OramaSearchBox
sourcesMap={{
description: 'content'
}}
resultMap={{
description: 'content'
}}
colorScheme={theme}
index={{
endpoint: 'orama endpoint',
api_key: 'orama key'
}}
suggestions={[
'DevNow 开源项目是做什么的?',
'DevNow 目前包含哪些内容?',
'如何快速部署 DevNow 项目?'
]}
/>
);
};
export default OramaBox;
1.3.4 更新 Search 组件
src/components/Search.tsx
import { OramaSearchButton } from '@orama/react-components';
import { useEffect, useState, type FC } from 'react';
const Search: FC = () => {
const [theme, setThemeState] = useState<'light' | 'dark' | 'system'>('light');
useEffect(() => {
const observer = new MutationObserver(() => {
const isDark = document.documentElement.classList.contains('dark');
setThemeState(isDark ? 'dark' : 'light');
});
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
return () => {
observer.disconnect();
};
}, []);
return <OramaSearchButton colorScheme={theme} size='small' className='mr-4' />;
};
export default Search;
1.3.5 更新
src/layouts/Layout.astro
---
import OramaBox from '@/components/OramaBox';
...
---
<body class='scrollbar'>
<OramaBox client:only='react' />
<Header />
...
</body>

以上就是全部的配置流程

二、DocSearch

DocSearch 是基于 Algolia 的搜索服务,官网地址为 https://docsearch.algolia.com/

由于有以下几个限制,暂时没有使用

  1. 您的网站必须是技术文档或技术博客。
  2. 您必须是网站的所有者,或者至少具有更新其内容的权限
  3. 您的网站必须公开可用
  4. 您的网站必须已准备好生产环境。

2.1 安装依赖

Terminal window
pnpm add

2.2 搜索组件

src/components/Search.tsx
import '@common/docsearch.css';
import config from '@config/index';
import { DocSearch } from '@docsearch/react';
const apiKey = import.meta.env.PUBLIC_SEARCH_API_KEY;
const apiId = import.meta.env.PUBLIC_SEARCH_APP_ID;
function Search() {
return (
<div className='mr-4 hidden lg:block'>
{config.search && (
<DocSearch
appId={apiId}
apiKey={apiKey}
indexName='devnow-laughingzhu'
maxResultsPerGroup={5}
/>
)}
</div>
);
}
export default Search;

2.3 配置环境变量

在 Vercel 上配置环境变量 PUBLIC_SEARCH_API_KEYPUBLIC_SEARCH_APP_ID 即可。

参数可以在 Algolia 控制台中找到,具体信息可以参考 https://www.laughingzhu.cn/posts/search-with-lunr