查询工具
useSearchCollection
useSearchCollection 组合式函数提供由 SQLite FTS5 支持的全文搜索,具备前缀匹配、BM25 排名和摘要片段功能。
用法
使用自动导入的 useSearchCollection 组合式函数在一个或多个集合中进行搜索。它会基于内容章节构建 FTS5 索引,并提供即时的排名搜索结果。
app.vue
<script setup lang="ts">
const { status, search } = useSearchCollection('docs')
const query = ref('')
const results = ref([])
watch(query, async (value) => {
results.value = value ? await search(value) : []
})
</script>
useSearchCollection 仅在客户端可用。FTS5 索引会在浏览器中使用 SQLite WASM 构建。类型
function useSearchCollection<T extends keyof PageCollections>(
collection: MaybeRefOrGetter<T | T[]>,
opts?: GenerateSearchSectionsOptions & { immediate?: boolean }
): {
status: Ref<'idle' | 'loading' | 'ready' | 'error'>
search: (query: string, opts?: SearchCollectionOptions) => Promise<SearchResult[]>
init: () => Promise<DatabaseAdapter>
}
API
参数
collection:单个集合键、集合键数组,或响应式 ref/getter。值变化时,会为新的集合重建 FTS 索引。opts:(可选)构建索引选项:immediate:是否立即开始构建索引。默认值为true。设为false可延迟到第一次调用search()或显式调用init()时再执行。ignoredTags:提取章节内容时要忽略的标签(例如['code'])。minHeading:拆分章节时使用的最小标题级别(例如'h2')。默认值为'h1'。maxHeading:拆分章节时使用的最大标题级别(例如'h4')。默认值为'h6'。
返回值
status:表示索引状态的响应式 ref:'idle'、'loading'、'ready'或'error'。search(query, opts?):执行搜索查询。返回包含排名结果的 promise。query:搜索字符串。自动支持前缀匹配(输入compo会匹配 “composable”)。opts:(可选)搜索选项:limit:最大结果数。默认值为50。fields:将搜索限制在特定列('title'或'content')中。minTermLength:跳过短于此值的术语。默认值为1。weights:控制排名行为。title:标题匹配的提升系数。默认值为10。content:内容匹配的提升系数。默认值为5。heading:是否让更高层级的章节(h1 > h2 > h3)排名更高。默认值为true。
snippet:返回高亮文本摘录。columns:对哪些列生成摘录(['title']、['content']或两者都可)。默认值为['content']。around:匹配项前后保留的 token 数。默认值为30。tag:用于高亮的 HTML 标签。默认值为'mark'。
init():手动触发索引构建。适用于immediate: false的情况。
结果类型
interface SearchResult {
collection: string
id: string
title: string
titles: string[]
level: number
content: string
rank: number
snippets?: { title?: string, content?: string }
}
示例
基本搜索
SearchPage.vue
<script setup lang="ts">
const { status, search } = useSearchCollection('docs')
const query = ref('')
const results = ref([])
async function onSearch() {
results.value = query.value
? await search(query.value, { limit: 20 })
: []
}
</script>
<template>
<UInput v-model="query" :disabled="status !== 'ready'" @input="onSearch" />
<ul>
<li v-for="result in results" :key="result.id">
<NuxtLink :to="result.id">{{ result.title }}</NuxtLink>
</li>
</ul>
</template>
多集合搜索
GlobalSearch.vue
<script setup lang="ts">
const { status, search } = useSearchCollection(['docs', 'blog'])
const results = ref([])
const query = ref('')
watch(query, async (value) => {
results.value = value
? await search(value, {
limit: 20,
snippet: { columns: ['content'], around: 40 },
})
: []
})
</script>
延迟初始化
LazySearch.vue
<script setup lang="ts">
const { status, search, init } = useSearchCollection('docs', {
immediate: false,
})
async function onFocus() {
if (status.value === 'idle') {
await init()
}
}
</script>
响应式集合
VersionedSearch.vue
<script setup lang="ts">
const version = ref('v4')
const collection = computed(() => `nuxt-${version.value}`)
const { status, search } = useSearchCollection(collection)
</script>
<template>
<select v-model="version">
<option>v3</option>
<option>v4</option>
<option>v5</option>
</select>
</template>
当集合值发生变化时,FTS 索引会被删除并为新集合重建。
与 queryCollectionSearchSections 的对比
useSearchCollection | queryCollectionSearchSections + Fuse.js | |
|---|---|---|
| 依赖 | 无(内置 FTS5) | 需要外部库 |
| 索引 | SQLite 倒排索引 | 内存中的 JS 扫描 |
| 速度 | O(log n) 索引查找 | 每次查询 O(n) |
| 摘要片段 | 内置 | 手动实现 |
| 拼写容错 | 仅前缀匹配 | 完整模糊匹配(编辑距离) |
| 多集合 | 原生支持 | 手动合并 |
当你需要快速、零依赖的搜索时,使用 useSearchCollection。当你需要容错拼写的模糊匹配时,使用带有 Fuse.js 或 MiniSearch 的 queryCollectionSearchSections。