feat(nbstore): optimize search performance (#11778)

now we can debug indexeddb performance by devtool

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/g3jz87HxbjOJpXV3FPT7/75cf686f-9bc4-4db3-86ac-12bba83e8d83.png)
This commit is contained in:
EYHN
2025-04-17 13:16:18 +00:00
parent 75df27a145
commit 5e9ad634b7
5 changed files with 116 additions and 33 deletions

View File

@@ -52,7 +52,9 @@ export class DocsSearchService extends Service {
occur: 'should',
queries: [
{
type: 'all',
type: 'match',
field: 'content',
match: query,
},
{
type: 'boost',

View File

@@ -6,7 +6,7 @@ import {
onStart,
} from '@toeverything/infra';
import { truncate } from 'lodash-es';
import { EMPTY, map, mergeMap, of, switchMap } from 'rxjs';
import { EMPTY, map, mergeMap, of, switchMap, throttleTime } from 'rxjs';
import type { DocRecord, DocsService } from '../../doc';
import type { DocDisplayMetaService } from '../../doc-display-meta';
@@ -50,6 +50,10 @@ export class DocsQuickSearchSession
items$ = new LiveData<QuickSearchItem<'docs', DocsPayload>[]>([]);
query = effect(
throttleTime<string>(1000, undefined, {
leading: false,
trailing: true,
}),
switchMap((query: string) => {
let out;
if (!query) {

View File

@@ -143,43 +143,42 @@ export class SearchMenuService extends Service {
// only search docs by title, excluding blocks
private searchDocs$(query: string) {
return this.docsSearch.indexer
.aggregate$(
.search$(
'doc',
{
type: 'boolean',
occur: 'must',
queries: [
type: 'match',
field: 'title',
match: query,
},
{
fields: ['docId', 'title'],
pagination: {
limit: 1,
},
highlights: [
{
type: 'match',
field: 'title',
match: query,
before: `<span style="color: ${cssVarV2('text/emphasis')}">`,
end: '</span>',
},
],
},
'docId',
{
hits: {
fields: ['docId', 'title'],
pagination: {
limit: 1,
},
highlights: [
{
field: 'title',
before: `<span style="color: ${cssVarV2('text/emphasis')}">`,
end: '</span>',
},
],
},
}
)
.pipe(
map(({ buckets }) =>
buckets.map(bucket => {
map(({ nodes }) =>
nodes.map(node => {
const id =
typeof node.fields.docId === 'string'
? node.fields.docId
: node.fields.docId[0];
const title =
typeof node.fields.title === 'string'
? node.fields.title
: node.fields.title[0];
return {
id: bucket.key,
title: bucket.hits.nodes[0].fields.title,
highlights: bucket.hits.nodes[0].highlights.title[0],
id,
title,
highlights: node.highlights.title[0],
};
})
)