@@ -60,6 +60,7 @@ export const chunkDiff = (
60
60
* 基于 MeiliSearch 实现的文档管理器
61
61
*/
62
62
export class DocManager {
63
+ #alreadyInit = false
63
64
/** MeiliSearch 客户端实例 */
64
65
#client: MeiliSearch ;
65
66
@@ -211,49 +212,72 @@ export class DocManager {
211
212
} ;
212
213
213
214
/**
214
- * 初始化文档管理器
215
+ * 操作前确保初始化完成
215
216
*/
216
- init = async ( ) => {
217
- console . info ( "Initializing DocManager..." ) ;
218
- await this . #ensureContainsFilterFeatureOn( ) ;
219
-
220
- this . #docIndex = await this . #getIndexOrCreate( `${ this . #indexPrefix} docs` ) ;
221
-
222
- // 获取已有的可筛选属性
223
- const docIndexFilterableAttributes =
224
- await this . #docIndex. getFilterableAttributes ( ) ;
225
-
226
- // 需要设置的可筛选的属性
227
- const docIndexFilterableAttributesNeedCreate = difference (
228
- [ "path" , "chunkHashs" ] ,
229
- docIndexFilterableAttributes
230
- ) ;
231
-
232
- // 设置可筛选属性
233
- if ( docIndexFilterableAttributesNeedCreate . length > 0 ) {
234
- console . info (
235
- `Creating filterable attributes for doc index: ${ docIndexFilterableAttributesNeedCreate } `
236
- ) ;
237
- await this . #docIndex. updateSettings ( {
238
- filterableAttributes : [
239
- ...docIndexFilterableAttributes ,
240
- ...docIndexFilterableAttributesNeedCreate ,
241
- ] ,
242
- } ) ;
217
+ #ensureInit = async ( ) => {
218
+ if ( ! this . #alreadyInit) {
219
+ await this . #init( )
220
+ this . #alreadyInit = true
243
221
}
222
+ }
244
223
245
- this . #docChunkIndex = await this . #getIndexOrCreate(
246
- `${ this . #indexPrefix} chunks`
247
- ) ;
224
+ /**
225
+ * 初始化文档管理器
226
+ */
227
+ #init = async ( ) => {
228
+ await Promise . all ( [
229
+ // 确保 ContainsFilter 功能开启
230
+ ( async ( ) => {
231
+ console . info ( "Initializing DocManager..." ) ;
232
+ await this . #ensureContainsFilterFeatureOn( ) ;
233
+ } ) ( ) ,
234
+ // 确保 docIndex 存在
235
+ ( async ( ) => {
236
+ this . #docIndex = await this . #getIndexOrCreate( `${ this . #indexPrefix} docs` ) ;
237
+
238
+ // 获取已有的可筛选属性
239
+ const docIndexFilterableAttributes = await this . #docIndex. getFilterableAttributes ( ) ;
240
+
241
+ // 需要设置的可筛选的属性
242
+ const docIndexFilterableAttributesNeedCreate = difference (
243
+ [ "path" , "chunkHashs" ] ,
244
+ docIndexFilterableAttributes
245
+ ) ;
246
+
247
+ // 设置可筛选属性
248
+ if ( docIndexFilterableAttributesNeedCreate . length > 0 ) {
249
+ console . info (
250
+ `Creating filterable attributes for doc index: ${ docIndexFilterableAttributesNeedCreate } `
251
+ ) ;
252
+ const task = await this . #docIndex. updateSettings ( {
253
+ filterableAttributes : [
254
+ ...docIndexFilterableAttributes ,
255
+ ...docIndexFilterableAttributesNeedCreate ,
256
+ ] ,
257
+ } ) ;
258
+ await this . #docIndex. waitForTask ( task . taskUid ) ;
259
+ }
260
+ } ) ( ) ,
261
+ // 确保 docChunkIndex 存在
262
+ ( async ( ) => {
263
+ this . #docChunkIndex = await this . #getIndexOrCreate(
264
+ `${ this . #indexPrefix} chunks`
265
+ ) ;
266
+ } ) ( )
267
+ ] ) ;
248
268
249
269
console . info ( "DocManager initialized successfully" ) ;
250
270
} ;
251
271
252
272
/** 获取已有 embedders */
253
- getEmbedders = async ( ) => await this . #docChunkIndex. getEmbedders ( )
273
+ getEmbedders = async ( ) => {
274
+ await this . #ensureInit( )
275
+ await this . #docChunkIndex. getEmbedders ( )
276
+ }
254
277
255
278
/** 重置已有 embedders */
256
279
resetEmbedders = async ( wait = false ) => {
280
+ await this . #ensureInit( )
257
281
const task = await this . #docChunkIndex. resetEmbedders ( )
258
282
if ( wait ) {
259
283
await this . #docChunkIndex. waitForTask ( task . taskUid )
@@ -262,6 +286,7 @@ export class DocManager {
262
286
263
287
/** 增删改 embedders */
264
288
updateEmbedders = async ( embedders : Embedders , wait = false ) => {
289
+ await this . #ensureInit( )
265
290
const task = await this . #docChunkIndex. updateEmbedders ( embedders )
266
291
if ( wait ) {
267
292
await this . #docChunkIndex. waitForTask ( task . taskUid )
@@ -403,6 +428,7 @@ export class DocManager {
403
428
} ;
404
429
405
430
upsertDoc = async ( path : string ) => {
431
+ await this . #ensureInit( )
406
432
// 查询该路径有无文档
407
433
const [ { mtimeMs } , remoteDocByPath ] = await Promise . all ( [
408
434
stat ( path ) ,
@@ -509,6 +535,7 @@ export class DocManager {
509
535
* @param path - 文档路径
510
536
*/
511
537
deleteDocByPath = async ( path : string ) => {
538
+ await this . #ensureInit( )
512
539
console . info ( `Deleting document at path: ${ path } ` ) ;
513
540
const doc = await this . #getDocByPathIfExist( path ) ;
514
541
@@ -524,6 +551,7 @@ export class DocManager {
524
551
* @param path - 目录路径
525
552
*/
526
553
deleteDocByPathPrefix = async ( path : string ) => {
554
+ await this . #ensureInit( )
527
555
console . info ( `Deleting all documents under path prefix: ${ path } ` ) ;
528
556
const getDocs = async ( ) =>
529
557
await this . #docIndex. getDocuments ( {
@@ -552,6 +580,7 @@ export class DocManager {
552
580
* @param hash - 文档 hash
553
581
*/
554
582
deleteDocByHash = async ( hash : string ) => {
583
+ await this . #ensureInit( )
555
584
console . info ( `Deleting document with hash: ${ hash } ` ) ;
556
585
const doc = await this . #getDocIfExist( hash ) ;
557
586
@@ -569,6 +598,7 @@ export class DocManager {
569
598
* @returns 返回搜索结果
570
599
*/
571
600
search = async ( query : string , opts ?: SearchParams ) => {
601
+ await this . #ensureInit( )
572
602
console . debug ( `Searching for query: ${ query } ` ) ;
573
603
const result = await this . #docChunkIndex. search ( query , opts ) ;
574
604
const hits = result . hits ;
0 commit comments