列表块“一炮三响”问题现状和改进提议

现状

众所周知,一个列表块至少包含了三个块。例如 * foo 的列表块实际的语法树结构和对应的 Markdown 为:

  1. 列表块容器 * foo
  2. 列表项块容器 * foo
  3. 段落块 foo

其对应的数据库表行数据为:

类型 markdown content
l * foo foo
i * foo foo
p foo foo

问题

这就导致在数据库上查询 foo 时,会同时命中三行,也就是“一炮三响”问题。当存在子列表时该问题尤为突出,表现为所有子列表上重复一次。例如:

* foo
  * bar

其对应的数据库表行数据为:

类型 markdown content
l * foo
* bar
foobar
i * foo
* bar
foobar
p foo foo
l * bar bar
i * bar bar
p bar bar

当搜索 bar 时,会命中 5 行作为结果集。

之前的改进

在搜索时加入了类型过滤,可以设置为过滤容器块,这样上述示例的搜索结果将减少为 1 行,即段落块 bar。

新改进提议

考虑在列表块和列表项块上的 markdown 和 content 字段上仅存储第一个块级子节点内容:

类型 markdown content
l * foo
foo
i * foo
foo
p foo foo
l * bar bar
i * bar bar
p bar bar

搜索 bar 时命中三行,即仅在当前列表块“一炮三响”。这个改进逻辑也匹配 引用容器块时自动渲染锚文本改进 #3126列表项折叠,除第一个子块外其余子块都隐藏 #3142

更进一步

容器块上的 markdown 和 content 字段完全留空,搜索时仅命中叶子块。

影响范围

广告 我要投放

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • fangly 1
    订阅者

    从用户的角度来看,一个比较理想的搜索体验:我只用关心我要查询什么,不用关心块的类型,软件自动帮我筛选出满足条件的块。也就是说我只需要 select * from blocks where markdown like "%x1%" and markdown like "%x2%" and markdown like "%x3%",然后软件自动搜索出同时包含 x1、x2、x3 的所有最小的块(也就是会自动去重)。在这个搜索结果的基础上,我还可以再限定块的类型等其他条件。

    当然这已经超出 sql 的范围,不加新字段,无论怎么修改数据库,只用 sql 来实现上面的逻辑肯定会非常复杂。我的看法:要么和 sql 可视化结合,可视化的背后是非常复杂的 sql;要么就是同咸鱼大佬说的,加一个新的字段便于去重,但加深度字段我想了一下貌似没法解决去重这个问题。

    举例:

    image.png

    在这种情况下,我只关心:我要搜索同时包含 a b c d 的块。然后软件自动把这 3 个红框中的内容搜索出来。

    当时这是非常理想的方式。

    3 操作
    fangly 在 2021-10-14 23:50:44 更新了该回帖
    fangly 在 2021-10-14 23:47:37 更新了该回帖
    fangly 在 2021-10-14 23:33:33 更新了该回帖
  • 其他回帖
  • leolee
    订阅者

    例如类似 select * from blocks where content like "%foo%" and depth = "0" 直接匹配 到叶子块
    然后 select * from blocks where content like "%foo%" and depth = "1" 匹配只有一层子块的容器块
    建表的时候文件结构应该已经遍历过了 所以加上深度字段应该不会消耗太多的资源吧
    类似的也可以加上 宽度字段 应该也可以增强检索能力 这个不用管爷爷辈的只管有多少个子块可能会更好弄一点?

  • deerain 1
    支持者 订阅者

    先占楼再看trollface


    疑虑 1:

    * foo
      * bar
    

    如果第一层的 i 只包含 * foo 不包含 * bar 了,会影响对 * foo 及其子列表的拖动和查询吗?这个太重要了。如果不能根据父节点查出子节点了,问题很大。

    疑虑 2:

    我分析问题的习惯是这样,一件事要先评估做与不做,而不是一开始就一头扎进对具体做法的思考。

    现在一炮三响对于熟练用户来说其实是很好解决的,就算要改进,我感觉主帖里写的这种改进方案带来的提升真的非常之小,还可能带来新的问题,而且也并没有提升对新手的友好程度(因为 l + i + p 的基本模型还是没变,如果一个新手从只会用 ctrl+p 进化到开始用 SQL 了,他在这轮改进之后面对的将是一个比原来更加不符合直觉的数据表)。

    不知道这轮改进的动机是什么,如果仅仅是为了解决搜索过程中的一炮三响,似乎没有什么改进的必要。

  • 88250
    订阅者 作者

    @participants 感谢各位讨论,这个提议我们搁置吧。

  • 查看全部回帖