关于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)