名詞一欄
haystack :Django的包可以對我們的model即興快速篩選和搜索
有四個引擎:solr,Xapian,Elasticsearc,whoosh
haystack :是個全文檢索框架
whoosh : python寫的輕量級引擎
額拉血Search : 妙查引擎
大致流程
配置
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', # 添加 'haystack', # 你的app 'blog', ]
使用的4個引擎配置

#### Elasticsearch示例 ```python HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine', 'URL': 'http://127.0.0.1:9200/', 'INDEX_NAME': 'haystack', }, } ``` #### Whoosh示例 ```python #需要設置PATH到你的Whoosh索引的文件系統位置 import os HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine', 'PATH': os.path.join(os.path.dirname(__file__), 'whoosh_index'), }, } # 自動更新索引 HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor' ``` #### Xapian示例 ```python #首先安裝Xapian后端(http://github.com/notanumber/xapian-haystack/tree/master) #需要設置PATH到你的Xapian索引的文件系統位置。 import os HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'xapian_backend.XapianEngine', 'PATH': os.path.join(os.path.dirname(__file__), 'xapian_index'), }, }
自動更新索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
定義索引模型
app下 search_indexes.py
注意點
1 必須在有且只有一個字段為 document=True 並且該字段變量名必須為text
2.表名必須是 字段index
3.必須重寫get_model
from haystack import indexes from app01.models import Article class ArticleIndex(indexes.SearchIndex, indexes.Indexable): #類名必須為需要檢索的Model_name+Index,這里需要檢索Article,所以創建ArticleIndex text = indexes.CharField(document=True, use_template=True)#創建一個text字段 #其它字段 desc = indexes.CharField(model_attr='desc') content = indexes.CharField(model_attr='content') def get_model(self):#重載get_model方法,必須要有! return Article def index_queryset(self, using=None): return self.get_model().objects.all()
新建模板
search
indexes
應用名
模型類名稱__text.txt
# 模板類_text 告訴這三個都要是使用檢索匹配 {{ object.title }} {{ object.desc }} {{ object.content }}
設置url
(r'^search/', include('haystack.urls')),
制定搜索結果的html頁面
temptags/search/search.html
page.object_list 是查詢的結果
還會給我們分頁 有上一頁下一頁
<!DOCTYPE html> <html> <head> <title></title> <style> span.highlighted { color: red; } </style> </head> <body> {% load highlight %} {% if query %} <h3>搜索結果如下:</h3> {% for result in page.object_list %} {# <a href="/{{ result.object.id }}/">{{ result.object.title }}</a><br/>#} <a href="/{{ result.object.id }}/">{% highlight result.object.title with query max_length 2%}</a><br/> <p>{{ result.object.content|safe }}</p> <p>{% highlight result.content with query %}</p> {% empty %} <p>啥也沒找到</p> {% endfor %} {% if page.has_previous or page.has_next %} <div> {% if page.has_previous %} <a href="?q={{ query }}&page={{ page.previous_page_number }}">{% endif %}« 上一頁 {% if page.has_previous %}</a>{% endif %} | {% if page.has_next %}<a href="?q={{ query }}&page={{ page.next_page_number }}">{% endif %}下一頁 » {% if page.has_next %}</a>{% endif %} </div> {% endif %} {% endif %} </body> </html> ```
重建索引
manage.py rebuild_index 數據放入進行索引
使用Jieba分詞
在 D:\python3\Lib\site-packages\haystack\ 路徑下新建ChineseAnalyzer.py文件
import jieba from whoosh.analysis import Tokenizer, Token class ChineseTokenizer(Tokenizer): def __call__(self, value, positions=False, chars=False, keeporiginal=False, removestops=True, start_pos=0, start_char=0, mode='', **kwargs): t = Token(positions, chars, removestops=removestops, mode=mode, **kwargs) seglist = jieba.cut(value, cut_all=True) for w in seglist: t.original = t.text = w t.boost = 1.0 if positions: t.pos = start_pos + value.find(w) if chars: t.startchar = start_char + value.find(w) t.endchar = start_char + value.find(w) + len(w) yield t def ChineseAnalyzer(): return ChineseTokenizer()
復制whoosh_backend.py文件,改名為whoosh_cn_backend.py
在這個文件里面修改
from .ChineseAnalyzer import ChineseAnalyzer #添加剛才模塊 查找 analyzer=StemmingAnalyzer() 改為 analyzer=ChineseAnalyzer()
搜索欄
```html <form method='get' action="/search/" target="_blank"> <input type="text" name="q"> #必須為q <input type="submit" value="查詢"> </form> ```
8.其它配置
from haystack.views import SearchView from .models import * class MySeachView(SearchView): def extra_context(self): #重載extra_context來添加額外的context內容 context = super(MySeachView,self).extra_context() side_list = Topic.objects.filter(kind='major').order_by('add_date')[:8] context['side_list'] = side_list return context #路由修改 url(r'^search/', search_views.MySeachView(), name='haystack_search'), ``` ### 高亮顯示 ```python {% highlight result.summary with query %} # 這里可以限制最終{{ result.summary }}被高亮處理后的長度 {% highlight result.summary with query max_length 40 %} #html中 <style> span.highlighted { color: red; } </style> ```