Skip to content

改进搜索排序规则 #4558

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
88250 opened this issue Apr 9, 2022 · 6 comments
Closed

改进搜索排序规则 #4558

88250 opened this issue Apr 9, 2022 · 6 comments
Assignees
Milestone

Comments

@88250
Copy link
Member

88250 commented Apr 9, 2022

#4546 继续改造。

@88250 88250 added this to the 1.9.9 milestone Apr 9, 2022
@88250 88250 self-assigned this Apr 9, 2022
@fanglypro
Copy link

fanglypro commented Apr 9, 2022

我的思路如下,供参考:

select *
from blocks
where ((content like '%foo%' or name like '%foo%' or alias like '%foo%' or memo like '%foo%'))
  and type IN ('d', 'h', 'i' ,  'c', 'm', 't', 's', 'p', 'html', 'iframe', 'query_embed', 'video', 'audio', 'widget')
order by case
             when name = 'foo' then 10
             when alias = 'foo' then 20
             when memo = 'foo' then 30
             when content = '%foo%' and type = 'd' then 40
             when content LIKE '%foo%' and type = 'd' then 41
             when name LIKE '%foo%' then 50
             when alias LIKE '%foo%' then 60
             when content = '%foo%' and type = 'h' then 70
             when content LIKE '%foo%' and type = 'h' then 71
             when fcontent = '%foo%' and type = 'i' then 80
             when fcontent LIKE '%foo%' and type = 'i' then 81
             when memo LIKE '%foo%' then 90
             when content LIKE '%foo%' and type != 'i' and type != 'l' then 100
             else 65535 end ASC, sort ASC, length DESC
limit 64

设计思路:

首先,把 name/alias/memo = 'foo' 作为一种手动置顶的方式,使其手动排在搜索结果的第一个。

之后,按照文档-标题-列表项层级顺序自顶向下,先搜文档,再搜标题,然后是列表项。对于类型内部,以列表项为例,首先搜的是fcontent字段,不搜content,然后,fcontent完全匹配的放在前列,不完全匹配的放在后面,对于不完全匹配的情况,按照length倒序(和之前不同,原因在下面叙述)。

其中,把不完全匹配的name/alias作为一种文档之下,其他块之上的存在,而不完全匹配的memo作为和段落块同级的存在。

至此,对于习惯于大纲列表的用户,所有内容都已经搜出来并按照层级排列,对于习惯于文档书写的用户,最常用引用的文档块和标题块也已经搜出来了。

剩下来没有搜索的块主要是段落块和超级块等容器块,这里描述下为什么我要length倒序,比如说,我块引用搜索“线段树”,结果排在前面是一个只含有"线段树"这三个字的段落块,这个段落块对于我的信息量为零,没有任何引用这个段落块的理由,因此,和前面的文档块的content/标题块的content/列表项块的fcontent不同,这三者的完全匹配,意味着子项有大量有价值的信息,而段落块作为叶子结点的完全匹配,无法带来任何有价值的信息,因此,这里的整体逻辑大致是(按照能带来的信息量大小):

完全匹配的父结点(对于列表项来说就是fcontent完全匹配)>不完全匹配的父结点>内容很长的叶结点>内容较短的叶结点>完全匹配的叶结点

同时,后面的content也不考虑列表项和列表块,因为前面已经搜出了最小可用内容了。

@88250
Copy link
Member Author

88250 commented Apr 9, 2022

感谢老铁,我们就按照这个设计实现看看效果 🙏

@fanglypro
Copy link

fanglypro commented Apr 11, 2022

有几个小问题:

问题1:现在对于有空格的情况应该是直接当成多关键字匹配了,因此无法正确识别有空格的情况下是否完全匹配,此时尤其对于英文用户,体验会明显不好,前面设计的规则会在大多数情况下失效,下图中,红框中的内容完全匹配,应该是在第一个:

image

一个解决方案是把length倒序改回成length正序,之前想到length倒序还有一个重要因素是因为列表项的content套娃,现在使用fcontent的话,这个问题没有了。

对于习惯大纲列表的用户,文档块/标题块/列表项块内部能够保证完全匹配的在前就可以了,至于非完全匹配的部分length正序还是倒序都差不多。至于段落块,和搜索关键词完全匹配的段落块大多数都出现在列表块中(因为用户很少会在单独的段落块中就写几个关键词),这些块前面出现过没有意义,但已经通过when content LIKE '%foo%' and type != 'i' and type != 'l' then 100 把它们扔到最后了。剩下来非完全匹配的段落块length正序还是倒序也都差不多。因此之前提到的段落块部分length正序造成的风险其实已经被用户写作习惯和其他排序规则规避掉了。

我看了一下roam research中的排序规则:对于page搜索,是多关键字匹配,length正序,对于block搜索,是按updated倒序。所以roam research里面对于block搜索的排序有很大问题,这也导致roam research中的一个知名用户Beau Haan所设计的zettelkasten方法需要特意设计结构,在block中加上一个空page,以规避block搜索的缺陷。

总结一下前面我的观点:length可以改回正序,因为length正序可能造成的风险目前已经通过其他的排序规则规避掉了。

问题2:在设置中设置了不区分大小写,判断是否完全匹配时,也应该不区分大小写,下图中,红框中的内容在不区分大小写的情况下完全匹配,应该是在第一个:

image

问题3:从1.9.8开始,对某个关键词进行第一次块引用搜索时,响应速度明显比以前慢,但紧接着对该关键词进行第二次块引用搜索时,响应速度正常,不清楚这是我的错觉,还是说这几次对搜索部分代码的修改确实有影响到性能。

@88250
Copy link
Member Author

88250 commented Apr 11, 2022

问题 1:目前的逻辑是对输入字符串按空格拆分,将其视为多个关键字,where 子句那里用 AND 连接。不要这个逻辑的话就没法方便地进行 AND 搜索了,估计得再想想。

问题 2:在 #4569 中改进。

问题 3:慢一些应该是正常的,只要不是太慢的话就好,后面我估计还是得用 SQLite FTS 解决搜索问题,现在没有用主要是卡在分词上。

@fanglypro
Copy link

fanglypro commented Apr 11, 2022

问题 1:目前的逻辑是对输入字符串按空格拆分,将其视为多个关键字,where 子句那里用 AND 连接。不要这个逻辑的话就没法方便地进行 AND 搜索了,估计得再想想。

问题 2:在 #4569 中改进。

问题 3:慢一些应该是正常的,只要不是太慢的话就好,后面我估计还是得用 SQLite FTS 解决搜索问题,现在没有用主要是卡在分词上。

对于问题1,我不是说不要这个逻辑,多关键字搜索逻辑我觉得没有问题,我提的解决方案是把length倒序改回成length正序,我在上面有说了,我之前的考虑有点问题,之前提到的length正序所造成的风险应该已经被用户的写作习惯和其他搜索排序规则给规避掉了。

顺带反馈个bug:

temp219

@88250
Copy link
Member Author

88250 commented Apr 11, 2022

收到,刚刚没有看到问题 1 描述更新,现在明白了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants