基于django-haystack的全文高级搜索查询
一、基于数据库的模糊查询这是一种很不理想的查询方法,并且对数据库的压力很大,查询的效率低下,我一般不建议采用这种查询方式。例如:想要查询models.py中MyNew类的字段(title)标题代码如下def search(request):keyword = request.GET.get("keyword")# 获取前端传回来的查询关键字newList = MyNew.objects.filte
一、基于数据库的模糊查询
这是一种很不理想的查询方法,并且对数据库的压力很大,查询的效率低下,我一般不建议采用这种查询方式。
例如:想要查询models.py中MyNew类的字段(title)标题
代码如下
def search(request):
keyword = request.GET.get("keyword") # 获取前端传回来的查询关键字
newList = MyNew.objects.filter(title__icontains=keyword) # MyNew中models.py 中title标题的查询
newName = "关于" + "\"" + keyword + "\"" + "的搜索结果"
return render(request, search.html)
二、基于haystack的全文高级搜索
django-haystack是一个专门提供搜索功能的Django第三方应用,它支持Solr
RlasticSearch、Whoosh、Xapian等多种搜索引擎,配合著名的中文自然语言处理库jieba分词,就可以实现高级查询。
这里使用Whoosh引擎和jieba分词。
安装这些包
pip install whoosh django-haystack jieba
安装好之后在项目的setting.py中做简单的配置,将django-haystack加入到INSTALLED_APPS中
INSTALLED_APPS = [
'django.contrib.admin',
...
...
# 添加查找应用
'haystack',
]
然后在setting.py文件末尾添加如下配置
# 配置全文高级搜索
HAYSTACK_CONNECTIONS = {
'default': {
# 此处为默认的WhooshEngine,后面会修改它,因此把它注释掉
# 'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',
'ENGINE': 'newsApp.whoosh_cn_backend.WhooshEngine',
'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
}
}
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 5 # 查询显示时每5页为分页
# 添加此项,当数据库改变时,会自动更新索引,非常方便
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
完成上述配置后接下来就是要告诉django-haystack使用哪些数据建立索引以及如何存放索引,如果要对newsApp 应用下的新闻内容进行全文检索,具体做法是在newsApp应用下建立一个search_indexes.py文件,然后添加代码如下:
from haystack import indexes
from .models import Mynew
class MyNewIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True) # document=True一般约定此字段名为text
# 使用的模型
def get_model(self):
return Mynew
# 返回的数据
def index_queryset(self, using=None):
return self.get_model().objects.all()
django-haystack规定如果要对某个App下的数据进行全文检索,就要在该APP下创建一个search_indexes.py文件,然后创建一个XX Indexable类(XX为含有被索引数据的模型,如这里是MyNew)。创建索引是因为索引就像是一本书的目录,可以为读者快速的导航和查找。
在这里每个索引必须有且只有一个字段为document=True,这代表了django-haystack和搜索引擎将使用此字段的内容作为索引。例如MyNew的title和description字段,这样就可以通过title和description内容来检索MyNew数据了。数据模板路径为:
templates/search/indexes/newsApp/MyNew_text.txt
创建的MyNew_text.text文件,编辑其中内容如下:
{{ object.title }}
{{ object.description }}
这个模板的作用是对MyNew中title和description两个字段建立索引,当检索的时候会对这两个字段做全文索引匹配,然后将匹配的结果排序后返回。
接下来配置URL
urlpatterns = [
path('admin/', xadmin.site.urls),
...
...
path('search/', include('haystack.urls')), # 添加haystack搜索的路径
]
编写newList.html文件的表单action属性
<div class="col-md-7 hidden-xs model-details-title-search">
<form method="get" action="{% url 'haystack_search' %}">
{% csrf_token %}
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="请输入关键词" required/>
<span class="input-group-btn">
<input type="submit" class="btn btn-default" value="查询"/>
</span>
</div>
</form>
</div>
注意输入文本框中name的属性,name="q",否则django-haystack默认的视图处理函数无法解析出数据。
这里使用的是Whoosh作为搜索引擎,但是在django-haystack中Whoosh分词器默认是英文分词器,因此需要把分词器换成jieba中文分词器。在haystack安装目录的backends文件夹中找到whoosh_cn_backend.py文件,并将其复制到newsApp文件夹下,然后找到如下代码进行修改。
schema_fields[field_class.index_fieldname] = TEXT(
stored=True,
analyzer=StemmingAnalyzer(),
field_boost=field_class.boost,
sortable=True,
)
改为
schema_fields[field_class.index_fieldname] = TEXT(
stored=True,
analyzer=ChineseAnalyzer(),
field_boost=field_class.boost,
sortable=True,
)
这样就将英文分词器改为中文分词器了,在头部引入
from jieba.analyse import ChineseAnalyzer
至此,整一个搜索框架的搭建就完成了。最后运行下述命令重建索引文件完成内容索引。
python manage.py rebulid_index
查看搜索效果。
更多推荐
所有评论(0)