爲甚麽搜尋經名比全文檢索更慢?

各位先進:

長久以來CBETA的搜尋就有這個問題。在目錄中搜尋關鍵字比全文檢索整部大正藏更慢。小弟用計時器測試了一下,以那先為例,在目錄中搜尋那先,到定位到《那先比丘經》,一共15秒,但在全文檢索中僅用時1.8秒就找到2641個結果。請問爲甚麽會出現這樣大的差異?是否有辦法使目錄搜尋更快?

討論區:

我的做法是在内存保存一份目录的数据结构,然后在内存里面搜索。自己写的算法。

因为第一,在内存中,第二,数据量少,所以速度很快。但是因为垃圾算法没有优化,有些抵消。但是总的来说,也还是非常快。肯定小于0.01秒了。

 

而全文搜索最后用的是es做的,速度就要慢一些,但是也应该是毫秒级的。

仅供参考。

Linux版本阅藏程序:

http://cbeta.buddhism.org.hk

 

cbeta's picture

您說的也沒錯,如果我們有足夠的時間、人力與資源,的確也有許多進一步改善的空間。

可惜我們目前往往是先期盼能在時限內把成果做出來,無法在細節上計較太多。

cbeta's picture

您好:

搜尋時間久,主要也是因為目錄搜尋不是全文檢索,它是逐條檢查,加上資料量很大,例如光是一個 "禪宗部類" 就有近八萬筆目錄資料,而且是樹狀目錄,需要逐層搜尋。

如果您是全部搜尋,有些資料還要先載入才能搜尋,那就要花更多時間了。

不過,如果您是要找那先比丘經,就不應該在「目錄」中搜尋,而是在「經目查詢」中去找,輸入「那先」二字,也是在瞬間就找到了。

目錄搜尋主要在您已經在找特定某冊的經文,希望查該冊的目錄,這樣才會快一點。而不是全部查詢,這樣當然會比較花時間了。

我这里是在内存里面建立了一个索引表。随手写的渣算法,但是对于查找目录速度还是足够快的,仅供参考:

 

444 class Search:
445     def __init__(self):
446         mulu = read_menu_file("static/sutra_sch.lst")
447         #pprint.pprint(m['T 大正藏'])
448         # d = mulu['T 大正藏']
449         def walk(d, result=[]):
450             '''遍历目录树'''
451             for x in d:
452                 if not d[x]:
453                     result.append(x)
454                 else:
455                     walk(d[x], result)
456             return result
457 
458 
459         result = walk(mulu)
460         result = [i.split(maxsplit=2) for i in result]
461         titles = [(i[0], ' '.join((i[1], i[2]))) for i in result]
462         # titles 是经号和title的对照表
463         # 生成索引表
464         self.index = {}
465         for i in titles:
466             z = 0
467             #print(i)
468             for j in i[1]:
469                 if j in self.index:
470                     self.index[j].append((i[0], z))
471                 else:
472                     self.index[j] = [(i[0], z),]
473                 #print(j, i[0], z)
474                 z += 1
475         for i in self.index:
476             # print(i)
477             v = self.index[i]
478             r = dict()
479             for j in v:
480                 if j[0] in r:
481                     r[j[0]].append(j[1])
482                 else:
483                     r[j[0]] = [j[1],]
484             # pprint.pprint((i, r))
485             self.index.update({i: r})
486         self.titles = dict(titles)
487 
488 
489     def search(self, title):
490         # title = opencc.convert(title, config='s2t.json')
491         # ( for zi in index)
492         a = (set(self.index.get(tt, {}).keys()) for tt in list(title))
493         return reduce(lambda x, y: x & y, a)
 

Linux版本阅藏程序:

http://cbeta.buddhism.org.hk

 

cbeta's picture

重點其實不在搜尋,你可以試看看,光是打開禪宗部類就要花好幾秒了。

時間主要都是花在樹狀目錄的資料載入。

可以预先载入一次,然后保存成二进制,以后直接读二进制。最简单的方案。几乎不怎么需要多余编码

Linux版本阅藏程序:

http://cbeta.buddhism.org.hk

 

cbeta's picture

目前目錄的特色就是可以載入各種組合的目錄,每個人使用的目錄都不同,所以預先載入並不符合使用的現況。因為或許有些人不需要搜尋目錄,但花上好幾秒預先載入,對他們來說並不是好的使用者經驗。

不過,若您可以很快寫出又快又好用的界面,歡迎提供大家使用,這是大眾之福,這也正是我們樂見的。如前所說,我們大部份時間都只能用在產生資料,程式方面只能提供堪用的版本,實在沒太多時間與資源全部投入在程式設計中。