就像在视图中的逻辑一样,我们通过query参数存在与否判断表单是否提交。默认不提交表单的页面,显示表单和一个搜索按钮,进行搜索后则显示结果总数和搜索到的文章列表。
由于表单里配置了反向解析,所以编辑blog应用的urls.py:
path(\'search/\', views.post_search, name=\'post_search\'),现在启动站点,到:8000/blog/search/可以看到表单页面如下:
输入查询内容然后点击搜索按钮,可以看到查询结果,如下所示:
现在我们就创建了全文搜索功能了。
4.5词干提取与搜索排名Django提供了一个SearchQuery类将一个查询词语转换成一个查询对象,默认会通过词干提取算法(stemming algorithms)转换成查询对象,用于更好的进行匹配。在查询时候还可能会依据相关性进行排名。PostgreSQL提供了一个排名功能,按照被搜索内容在一条数据里出现的次数和频率进行排名。
编辑blog应用的views.py文件:
from django.contrib.postgres.search import SearchVector, SearchQuery, SearchRank然后找到下边这行:
results = Post.objects.annotate(search=SearchVector(\'title\', \'body\'),).filter(search=query)替换成如下内容:
search_vector = SearchVector(\'title\', \'body\') search_query = SearchQuery(query) results = Post.objects.annotate(search=search_vector, rank=SearchRank(search_vector, search_query) ).filter(search=search_query).order_by(\'-rank\')在上边的代码中,先创建了一个SearchQuery对象,用其过滤结果。之后使用SearchRank方法将结果按照相关性排序。打开:8000/blog/search/并且用不同的词语来测试搜索。下边是使用\'django\'搜索的示例:
4.6搜索权重当按照相关性进行搜索时,可以给不同的向量赋予不同的权重,从而影响搜索结果。例如,可以对在标题中搜索到的结果给予比正文中搜索到的结果更大的权重。编辑blog应用的views.py文件:
search_vector = SearchVector(\'title\', weight=\'A\') + SearchVector(\'body\', weight=\'B\') results = Post.objects.annotate( search=search_vector, rank=SearchRank(search_vector, search_query) ).filter(rank__gte=0.3).order_by(\'-rank\')在上边的代码中,给title和body字段的搜索向量赋予了不同的权重。默认的权重D,C,B,A分别对应 0.1, 0.2, 0.4和1。我们给title字段的搜索向量赋予权重1.0,给body字段的搜索向量的权重是0.4,说明文章标题的重要性要比正文更重要,最后设置了只显示综合权重大于0.3的搜索结果。
4.7三元相似性搜索还有一种搜索方式是三元相似性搜索。三元指的是三个连续的字符。通过比较两个字符串里,有多少个三个连续的字符相同,可以检测这两个字符串的相似性。这种搜索方式对于不同语言中的相近单词很高效。
如果要在PostgreSQL中使用三元检索,必须安装一个pg_trgm扩展。
在系统命令行执行下列命令连接到数据库:
psql blog然后输入下列数据库指令:
CREATE EXTENSION pg_trgm然后编辑视图来增加三元相似搜索功能,编辑blog应用的views.py,这一次需要导入的新组件:
from django.contrib.postgres.search import TrigramSimilarity然后将Post搜索查询对象替换成如下这样:
results = Post.objects.annotate( similarity=TrigramSimilarity(\'title\',query), ).filter(similarity__gte=0.1).order_by(\'-similarity\')打开:8000/blog/search/,然后试验不同的三元相似锁边,下边的例子显示了使用yango想搜索django的结果: