QuickStart
下面是一个简短的例子:
>>>from whoosh.index import create_in
>>>from whoosh.fields import *
>>>schema = Schema(title = TEXT(stored = True),path =ID(stored=True),content=TEXT)
>>>ix =create_in("indexer",schema)(这里的“indexer”实际上是一个目录,因此按照这个步骤来会出错,你得先创建目录,译者注)
>>>writer = ix.writer()
>>>writer.add_document(title=u"Firstdocument",path=u"/a",
content = u"this is the first document we've add!")
>>> writer.add_document(title=u"Second document",path=u"/b",
... content=u"The second one is even more interesting!")
>>> writer.commit()
>>> from whoosh.qparser import QueryParser
>>> with ix.searcher() as searcher:
query =QueryParser("content", ix.schema).parse("first")
results =searcher.search(query)
results[0]
{"title": u"First document", "path": u"/a"}
Index和Schema对象
在开始使用whoosh之前,你需要一个index对象,在你第一次创建index对象时你必须定义一个Schema对象,Schema对象列出了Index的所有域。一个域就是Index对象里面每个document的一个信息,比如他的题目或者他的内容。一个域能够被索引(就是能被搜索到)或者被存储(就是得到索引之后的结果,这对于标题之类的索引非常有用)
下面这个schema对象有两个域,“title”和“content”
from whoosh.fields import Schema,TEXT
schema = Schema(title=TEXT,content=TEXT)
当你创建index的时候你创建一次schema对象就够了,schema是序列化并且和index存储的。
当你创建索引对象的时候,需要用到关键字参数来将域名和类型建立映射关系,域的名字和类型决定了你在索引什么和什么事可搜索的。whoosh有很多非常有用的预定义域类型,你可以非常容易的创建他们。如下:
whoosh.fields.ID
这种类型简单地索引(选择性存储)这个域里面所有的值作为一个单元(意思就是它不会把里面的词分开)这个对于像存储文件路径,URL,日期等等非常有用
whoosh.fileds.STROED
这个域存储文本但是不索引,他不被索引也不可被搜索,当你需要给用户展示文本搜索结果信息的时候非常有用
whoosh.fileds.KEYWORD
这种类型是为空格或者逗号分词的关键字设计的。他可以被索引和被搜索到(并且选择性的存储)。为了保存空格他不支持词组搜索
whoosh.fields.TEXT
这是正文文本,他索引(并且选择性存储)文本并且存储词语位置来支持短语搜索
whoosh。fields.NUMERIC
数字类型,可以存储整数和浮点数
whoosh.fields.BOOLEAN
布尔类型
whoosh.fields.DATETIME
日期类型,以后有详细介绍
whoosh.fields.NGRAM和whoosh.fields.NGRAMWORDS
这种类型把文本分成n-grams(以后详细介绍)
(为了简便,你可以不给域类型传递任何参数,你可以仅仅给出类型名字whoosh会为你创造类的实例)
from whoosh.fields import Schema,STORED,ID,KEYWORD,TEXT
schema = Schema(title=TEXT(stored=True),content=TEXT,
path=ID(stored=True),tags=KEYWORD,icon=STORED)
一旦你有了schema对象,你可以用create_in函数创建索引:
import os.path
from whoosh.fields import create_in
if not os.path.exists("index"):
os.mkdir("index")
ix =create_in("index",schema)
(这创造了一个存储对象来包含索引,存储对象代表存储索引的媒介,通常是文件存储,也就是存在目录的一系列文件)
在你创建索引之后,你可以通过open_dir函数方便地打开它
from whoosh.index import open_dir
ix = open_dir("index")
IndexWriter对象
好了我们有了索引对象现在我们可以添加文本。索引对象的writer()方法返回一个能够让你给索引添加文本的IndexWriter对象,IndexWriter对象的add_document(**kwargs)方法接受关键字参数:
writer = ix.writer()
writer.add_document(title=u"My document", content=u"This is mydocument!",
path=u"/a",tags=u"first short", icon=u"/icons/star.png")
writer.add_document(title=u"Second try", content=u"This is thesecondexample.",path=u"/b", tags=u"second short", icon=u"/icons/sheep.png")
writer.add_document(title=u"Third time's the charm",content=u"Examples aremany."path=u"/c", tags=u"short", icon=u"/icons/book.png")
writer.commit()
两个重点:
1.你不必要把每一个域都填满,whoosh不关系你是否漏掉某个域
2.被索引的文本域必须是unicode值,被存储但是不被索引的域(STORED域类型)可以是任何和序列化的对象
如果你需要一个既要被索引又要被存储的文本域,你可以索引一个unicode值但是存储一个不同的对象(某些时候非常有用)
writer.add_document(title=u"Title to be indexed",_stored_title=u"Stored title")
使用commit()方法让IndexWriter对象将添加的文本保存到索引
writer.commit()
Searcher对象
在搜索文本之前,我们需要一个Searcher对象
searcher = ix.searcher()
推荐用with表达式来打开搜索对象以便searcher对象能够自动关闭(searcher对象代表打开的一系列文件,如果你不显式的关闭他们,系统会慢慢回收他们以至于有时候会用尽文件句柄)
with in.searcher() as searcher:
...
这等价于:
try:
searcher =ix.searcher()
...
finally:
searcher.close()
Searcher对象的search方法使用一个Query对象,你可以直接构造query对象或者用一个queryparser来得到一个查询语句
#Construct query objects directly
from whoosh.query import *
myquery =And([Term("content",u"apple"),Term("content","bear")])
用parser得到一个查询语句,你可以使用默认的qparser模块里面的queryparser。QueryParser构造器的第一个参数是默认的搜索域,这通常是“正文文本”域第二个可选参数是用来理解如何parse这个域的schema对象:
#Parse a query string
from whoosh.qparser import QueryParser
parser = QueryParser("content",ix.schema)
myquery = parser.parse(querystring)
一旦你有了Searcher和query对象,你就可以使用Searcher对象的search()方法进行查询并且得到一个结果对象
>>>results = searcher.search(myquery)
>>>print len(results)
1
>>>print results[0]
{"title": "Second try", "path": /b,"icon":"/icon/sheep.png"}
默认的QueryParser实现了一种类似于lucene的查询语言,他允许你使用连接词AND和OR以及排除词NOT和组合词together来搜索,他默认使用AND将从句连结起来(因此默认你所有的查询词必须都在问当中出现)
>>> print(parser.parse(u"render shade animate"))
And([Term("content", "render"), Term("content", "shade"),Term("content", "animate")])
>>> print(parser.parse(u"render OR (title:shadekeyword:animate)"))
Or([Term("content", "render"), And([Term("title", "shade"),Term("keyword", "animate")])])
>>> print(parser.parse(u"rend*"))
Prefix("content", "rend")
Whoosh处理结果包含额外的特征,例如:
1.按照结果索引域的值排序,而不是按照相关度
2.高亮显示原文档中的搜索词
3.扩大查询词给予文档中找到的少数值
4.分页显示(例如显示1-20条结果,第一到第四页的结果)
关于如何搜索后面有详细介绍
好,第一篇到此为止,后面会陆陆续续地翻译出来,算是开个头吧