【搜尋引擎】Whoosh——Schema介紹
關於Schema和Field
Schema指明瞭需要索引的文件的域(field)。
每個文件都可以有多個field,例如標題,正文,url,日期等。
有些field可以被索引,有些field可以和文件一起儲存,這樣field的值可以在搜尋結果中展示出來,有些索引即可以被索引也可以被儲存。
schema是文件中所有field的集合,每一個文件可能只擁有schema中一個field子集。
Field Types
whoosh.fields.TEXT
- 適用於正文文字,對文字進行索引(可儲存),同時儲存項的位置以提供搜尋功能。
- 預設使用StandardAnalyzer,可以通過指明analyzer關鍵字來設定其他analyzer。
- TEXT預設對每一個索引項的位置資訊進行儲存,以便進行pharse可以通過設定TEXT(phrase=False)來關閉。
- TEXT預設是不儲存的,可以通過TEXT(stored=True)來設定。
whoosh.fields.KEYWORD
- 這個型別是為以空格或者逗號為分隔符的關鍵詞建立的。可以被索引也可以被搜尋,儲存。如果要儲存空格,則不支援短語搜尋。
- 使用stored=True來儲存域中的value。
- 關鍵詞被設定為預設以空格為分隔符,可以通過設定commas=True來使用逗號分隔。
- 如果要使用keywords域來進行搜尋,設定scorable為True。
whoosh.fields.ID
- ID型別對field的整個值做索引,即將field的值作為一個整體不可拆分,這個型別不儲存頻次資訊。
- 這個型別適合儲存url或是path,date,category,類似的其值必須被看做一個整體,並且每一個文件僅含有一個值的域。
- ID field預設是不儲存的。
whoosh.fields.STORED
STORED域僅僅是和文件一起儲存,不會被索引和搜尋,當你想儲存一些資訊隨搜尋結果一起展示時,可以將這些資訊設定為STORED。
whoosh.fields.NUMERIC
這個型別儲存整型,長整型或是浮點型資料。
whoosh.fields.DATETIME
儲存日期型資料
whoosh.fields.BOOLEAN
儲存布林型資料,(yes,no;true,false;1,0;t,f)
whoosh.fields.NGRAM
TBD
構建Schema
使用如下語句來構建一個Schema,同時指明文件中的field以及field的資料型別:
from whoosh.fields import Schema, TEXT, KEYWORD, ID, STORED
from whoosh.analysis import StemmingAnalyzer
schema = Schema(from_addr=ID(stored=True),
to_addr=ID(stored=True),
subject=TEXT(stored=True),
body=TEXT(analyzer=StemmingAnalyzer()),
tags=KEYWORD)
使用create_in()或者create_index()來建立索引:
ix = create_in("index", schema)
可以使用writer物件的add_field()和remove_field()方法來修改schema:
writer = ix.writer()
writer.add_field("fieldname", fields.TEXT(stored=True))
writer.remove_field("content")
writer.commit()
當刪除schema中的field時,index檔案在得到優化前並不會因此而變小,以下是優化方法。
writer = ix.writer()
writer.add_field("uuid", fields.ID(stored=True))
writer.remove_field("path")
writer.commit(optimize=True)
切記在優化前不要將與被刪除field同名的field新增到index中。
動態Field
我們可以使用萬用字元來聯絡符合條件的field。例如:
schema = fields.Schema(...)
# Any name ending in "_d" will be treated as a stored
# DATETIME field
schema.add("*_d", fields.DATETIME(stored=True), glob=True)
所有名字以‘_d’為結尾的field會被設定為DATETIME。
設定諸如此類的動態field時需要設定glob為True。
刪除動態field:
writer = ix.writer()
writer.remove_field("*_d")
writer.commit()
使用示例:
schema = fields.Schema(path=fields.ID)
schema.add("*_id", fields.ID, glob=True)
ix = index.create_in("myindex", schema)
w = ix.writer()
w.add_document(path=u"/a", test_id=u"alfa")
w.add_document(path=u"/b", class_id=u"MyClass")
# ...
w.commit()
qp = qparser.QueryParser("path", schema=schema)
q = qp.parse(u"test_id:alfa")
with ix.searcher() as s:
results = s.search(q)
以上程式碼將所有名稱以'_id'為結尾的field都設定為ID型別,可以減少一定工作量,做到批量操作。
高階schema設定
Field boosts
為域設定權重,以區分不同Field的重要程度。例如將在title中發現索引項的得分設定為兩倍於其他Field中的得分。
schema = Schema(title=TEXT(field_boost=2.0), body=TEXT)