Skip to content

[Feature] Meilisearch在自动更新索引开启情况下应该调用BatchIndex 减少POST请求数量 #1417

@ImoutoHeaven

Description

@ImoutoHeaven

请确认以下事项

  • 我已确认阅读并同意 AGPL-3.0 第15条
    本程序不提供任何明示或暗示的担保,使用风险由您自行承担。

  • 我已确认阅读并同意 AGPL-3.0 第16条
    无论何种情况,版权持有人或其他分发者均不对使用本程序所造成的任何损失承担责任。

  • 我确认我的描述清晰,语法礼貌,能帮助开发者快速定位问题,并符合社区规则。

  • 我已确认阅读了OpenList文档

  • 我已确认没有重复的问题或讨论。

  • 我认为此问题必须由OpenList处理,而非第三方。

  • 我已确认此功能尚未被实现。

  • 我已确认此功能是合理的,且有普遍需求,并非我个人需要。

需求描述

问题背景

当 Meilisearch 作为搜索引擎时,OpenList 支持自动更新索引功能。在用户浏览目录时,系统会自动检测新增文件并将其添加到搜索索引中。

当前实现存在的问题

internal/search/build.goUpdate 函数中(第202-268行),当检测到目录下有新增文件时,采用的是逐个文件索引的方式:

for i := range objs {
    if toAdd.Contains(objs[i].GetName()) {
        if !objs[i].IsDir() {
            err = Index(ctx, parent, objs[i])  // 每个文件一个POST请求
            if err != nil {
                log.Errorf("update search index error while index new node: %+v", err)
                return
            }
        }
    }
}

由于 Update 函数的触发机制是用户浏览一个目录就触发一次

用户浏览目录
  → op.List(ctx, storage, path)                    // fs.go:138
     → storage.List(ctx, dir, args)               // 获取目录下所有文件
        → HandleObjsUpdateHook(reqPath, files)    // fs.go:153,异步调用
           → Update(parent, objs)                 // build.go:202

因此,Update 函数一次性接收到一个目录下的所有文件,具备调用BatchIndex进行批量索引的条件。

实现思路

将逐个文件索引改为批量索引,利用已有的 BatchIndex 函数,该函数内部使用 Meilisearch SDK 的 AddDocumentsInBatchesWithContext 方法,会按照 10,000 个文档为单位进行分批处理。

修改细节

位置internal/search/build.goUpdate 函数(第245-276行)

修改前

for i := range objs {
    if toAdd.Contains(objs[i].GetName()) {
        if !objs[i].IsDir() {
            log.Debugf("add index: %s", path.Join(parent, objs[i].GetName()))
            err = Index(ctx, parent, objs[i])  // 逐个索引
            if err != nil {
                log.Errorf("update search index error while index new node: %+v", err)
                return
            }
        } else {
            // build index if it's a folder
            ...
        }
    }
}

修改后

// collect files to add in batch
var toAddObjs []ObjWithParent
for i := range objs {
    if toAdd.Contains(objs[i].GetName()) {
        if !objs[i].IsDir() {
            log.Debugf("add index: %s", path.Join(parent, objs[i].GetName()))
            toAddObjs = append(toAddObjs, ObjWithParent{
                Parent: parent,
                Obj:    objs[i],
            })
        } else {
            // build index if it's a folder
            ...
        }
    }
}
// batch index all files at once
if len(toAddObjs) > 0 {
    err = BatchIndex(ctx, toAddObjs)
    if err != nil {
        log.Errorf("update search index error while batch index new nodes: %+v", err)
        return
    }
}

理论上应该对于一个文件夹内包含大量文件的情况会有性能提升。

附加信息

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions