Djapian - 过滤结果
我在用Djapian通过关键词搜索对象,但我想对结果进行筛选。如果能用Django的QuerySet API来做这件事就好了,比如说:
if query.strip():
results = Model.indexer.search(query).prefetch()
else:
results = Model.objects.all()
results = results.filter(somefield__lt=somevalue)
return results
但是Djapian返回的是一组ResultSet
对象,这些对象是Hit
类型的,而不是Model
类型的。当然,我可以在Python里手动筛选这些对象,但如果要筛选所有对象(当查询为空时),这就不太现实了——我得从数据库里把整个表都取出来。
我在用Djapian的时候是不是没戏了?
2 个回答
0
我不太了解Djapian,但我对xapian比较熟悉。在Xapian中,你可以用一个叫做MatchDecider的东西来过滤搜索结果。
这个MatchDecider的决策函数会在每一个符合搜索条件的文档上被调用,所以在这里对每个文档都去数据库查询并不是个好主意。不过,你当然可以访问文档中的值。
举个例子,在ubuntuusers.de网站上,我们有一个xapian数据库,里面存储了博客文章、论坛帖子、行星条目、维基条目等等,每个文档都有一些额外的访问信息作为值存储。在查询之后,一个AuthMatchDecider会过滤出潜在的文档,并返回过滤后的结果集,这些结果会展示给用户。
如果决策过程很简单,比如说某个字段小于某个值,你也可以直接把这个字段的值加到文档的值中(使用xapian提供的sortable_serialize
函数),然后在原始查询中添加一个OP_FILTER
和OP_VALUE_RANGE
的查询。
4
我查看了它的源代码,发现Djapian有一个可以用来过滤结果的方法。我刚刚试了下面的代码,似乎可以正常工作。
我的索引器如下:
class MarketIndexer( djapian.Indexer ):
fields = [ 'name', 'description', 'tags_string', 'state']
tags = [('state', 'state'),]
这是我过滤结果的方法(第一行是为了处理通配符的,不用在意):
objects = model.indexer.search(q_wc).flags(djapian.resultset.xapian.QueryParser.FLAG_WILDCARD).prefetch()
objects = objects.filter(state=1)
执行后,现在它会返回状态等于“1”的Market
。