halo-dev / halo

强大易用的开源建站工具。
https://www.halo.run
GNU General Public License v3.0
33.52k stars 9.63k forks source link

插件支持刷新搜索索引 #5339

Closed Rainsheep closed 3 months ago

Rainsheep commented 8 months ago

你当前使用的版本

2.12

描述一下此特性

在最新的 2.12 版,官方去除了 halo 启动时刷新索引的功能。 会出现如下问题:用户在已有 Post 的前提下去安装 搜索类插件,必须手动刷新索引才能加载已发布的文章,增加了用户使用的复杂性,况且很多用户不知道刷新索引。

建议:考虑将 IndicesService 加入到 shareApplicationContext 中,使容器拥有刷新索引的能力。 将刷新索引和 halo 解耦,提升 halo 的性能。 只有装了插件的人才会自动刷新索引,也算一种这折中方案。

5333

附加信息

No response

JohnNiang commented 8 months ago

Hi @Rainsheep , thank you for reaching out here!

关于这个功能,我还是有一个小疑问:即使我们让插件有能力调用 IndicesService,那么插件在每次启动的时候都会去刷新索引么?或者说应该什么时机会去自动刷新搜索引擎呢?

/kind feature /area core /area plugin

Rainsheep commented 8 months ago

@JohnNiang 官方将功能开放给插件开发者,怎么调用由开发者决定。

我从开发者的角度阐述一下这件事。

刷新索引的作用有两个:

  1. 新增索引。 --这是必须的
  2. 全量更新索引,防止索引有误。 --这是非必要的,防范性的。

要不要刷新索引,无非就是在索引的准确性和性能方面做一个取舍。

追求准确性: 插件启动时刷新索引,会牺牲启动时的性能,我认为影响不大,毕竟是一次性工作,而且只影响安装了插件的用户。 对于开发者来说,启动时刷新索引是一种简单粗暴的方式(大多数开发者会这样选择)。

这种牺牲性能的方式牺牲的是谁的性能?

追求性能: 这种方式只需要保障 “新增索引”,索引有误的话依旧由用户手动重置。 举一个简单的实现方式:启动时发现,现有索引数量 != 预期索引数量,就去刷新索引。

JohnNiang commented 8 months ago

目前我想到一个 Console 端解决方案:

适配 console,保证打开插件的时候弹窗提示用户是否需要更新索引,让使用者决定是否需要“重新刷新索引”,如果用户确认,则直接调用“重新刷新索引”的接口即可。

如果要适配后端的,则至少需要等待 Halo 2.13。

Rainsheep commented 8 months ago

@JohnNiang 有不足:

  1. 插件启动后,用户修改了 search 插件的 host,切换到了新的搜索服务,也需要刷新索引。
  2. 插件想在半夜重置索引来保证准确性。

是将功能放开给插件还是保证使用规范的统一,由官方来抉择。

JohnNiang commented 8 months ago

/assign

我将尝试把 IndicesService 作为 PluginApplicationContext bean 的一员,并移动到 api module 中。

guqing commented 8 months ago

/assign

我将尝试把 IndicesService 作为 PluginApplicationContext bean 的一员,并移动到 api module 中。

建议这个先不做 先重构一下搜索引擎的扩展 目前只能添加文章 希望可以添加其他的如moments或者doc等 参考 https://github.com/halo-dev/halo/issues/5202

JohnNiang commented 8 months ago

Hi @guqing ,我这里有几个小问题:

最后,我更建议提供新的扩展点来重构搜索功能。

guqing commented 8 months ago

Hi @guqing ,我这里有几个小问题:

  • 如果我们重构搜索引擎的扩展,以前的扩展(run.halo.app.search.post.PostSearchService)是否还生效呢?

  • 如果仍旧生效且重构工作不能发布在 2.13,建议先将 IndicesService 加入到 PluginApplicationContext bean 中。

最后,我更建议提供新的扩展点来重构搜索功能。

旧的目前只有core和另外一个搜索插件在使用,等重构之后可以为那个插件提一个pr适配一下然后废弃当前的功能以新的为准 毕竟之前没有提供搜索扩展的文档后续版本变动应该是正常的, 关联 https://github.com/halo-dev/halo/issues/5184

JohnNiang commented 8 months ago

Hi @Rainsheep ,不如我们先关注一下 https://github.com/halo-dev/halo/issues/5202,并在重构的时候考虑到当前 Issue 中所反馈的问题。

/unassign /milestone clear

Rainsheep commented 4 months ago

旧案重提,辛苦关注。 @JohnNiang @guqing 2.15 版本了,发现官方并没有做任何改动。。。 搜索方面看起来也没什么进展? 能否放开刷新索引功能?

ruibaby commented 4 months ago

旧案重提,辛苦关注。 @JohnNiang @guqing 2.15 版本了,发现官方并没有做任何改动。。。 搜索方面看起来也没什么进展? 能否放开刷新索引功能?

我们暂时计划会在接下来的两个版本(2.17 和 2.18)来解决这些遗留问题,之前和搜索相关的 issue 都已经放在了 2.17 的 milestone。

https://github.com/halo-dev/halo/milestone/89

Rainsheep commented 4 months ago

get,期待

JohnNiang commented 4 months ago

/assign /milestone 2.17.x

JohnNiang commented 3 months ago

Hi @Rainsheep , 可以帮忙测试一下正在重构的搜索引擎扩展么?非常欢迎提供宝贵的意见和建议。

请参考:https://github.com/halo-dev/halo/pull/6082/files#diff-df8f54d51fe1574bc3fd18a2e9e6c23fd8c4276a8906dacfc249d91f28ebc4c1

集成步骤:

  1. 构建源码并发布到 Maven 本地仓库
    gh pr checkout 6082
    ./gradlew publishToMavenLocal
  2. 修改插件的 build.gradle

    repositories {
        mavenLocal()
        // 其他仓库
    }
    
    dependencies {
        // 确保这里的版本和刚刚发布的 Maven 包一致
        implementation platform('run.halo.tools.platform:plugin:2.17.0-SNAPSHOT')
  3. 实现 run.halo.app.search.SearchEngine 接口
Rainsheep commented 3 months ago

@JohnNiang get,个人时间原因,周五晚上测试并反馈。

Rainsheep commented 3 months ago

@JohnNiang

  1. 新建文章是会调用两次增加索引。 看起来问题不大。
  2. 插件依旧无法刷新索引
  3. 添加/更新索引时收到的分类和标签与预期不符; 比如文章的分类是 “默认分类“,标签是 "Halo" ,收到的是 categories=[76514a40-6ef1-4ed9-b58a-e26945bde3ca], tags=[c33ceabb-d8f1-4711-8991-bb8f5c92ad7c]。 分类是 “翻墙”,标签是“科学上网”,收到的是"categories":["category-EUEuA"],"tags":["tag-XrQGP"], 插件无法根据分类和标签搜索
JohnNiang commented 3 months ago

Hi @Rainsheep,感谢花时间测试!

  1. 如果新增文章的时候,直接点击了发布按钮,则会触发两次更新。第一次是创建文章,第二次是发布文章。
  2. 可以发送 run.halo.app.search.event.HaloDocumentRebuildRequestEvent 事件触发重启。
  3. 我暂时还没有测试根据分类和标签进行查询的功能。后续我会增加相应的功能。
Rainsheep commented 3 months ago

@JohnNiang 关于第二点,插件中调用 ApplicationEventPublisher.publishEvent(new HaloDocumentRebuildRequestEvent(this)); 没有刷新索引呀。 我理解插件和 halo rootContext 是两个容器,插件内的普通事件,外面收不到。 看起来也没有对 HaloDocumentRebuildRequestEvent 做特殊处理

JohnNiang commented 3 months ago

@JohnNiang 关于第二点,插件中调用 ApplicationEventPublisher.publishEvent(new HaloDocumentRebuildRequestEvent(this)); 没有刷新索引呀。 我理解插件和 halo rootContext 是两个容器,插件内的普通事件,外面收不到。 看起来也没有对 HaloDocumentRebuildRequestEvent 做特殊处理

关于共享事件的发布和监听,请参考 https://github.com/halo-dev/halo/pull/6081

JohnNiang commented 3 months ago

@JohnNiang 关于第二点,插件中调用 ApplicationEventPublisher.publishEvent(new HaloDocumentRebuildRequestEvent(this)); 没有刷新索引呀。 我理解插件和 halo rootContext 是两个容器,插件内的普通事件,外面收不到。 看起来也没有对 HaloDocumentRebuildRequestEvent 做特殊处理

Hi @Rainsheep ,我刚测试的时候也发现无法在插件启动的时候重建索引。主要原因是:如果我们在 plugin#start 方法中发送事件,Halo Core 中是可以收到重建索引请求,但此时插件的状态还不是 Started,导致 Halo Core 这边获取不到插件中实现的搜索引擎,所以也就没有任何效果。

我将尝试提供一个启动成功后的事件供插件实现自定义逻辑。