首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Flask 整合 Whoosh 實作全文搜尋教學

     編輯:更多程式設計知識

關聯式資料庫對全文搜尋支援有限且不標準。本文採用純 Python 實作的 Whoosh 搜尋引擎,搭配 Flask-WhooshAlchemy 擴展,為微型部落格加入全文搜尋功能。

為何選擇 Whoosh?

  • 純 Python,跨平台無相依性
  • 提供 Flask 擴展,整合 Flask-SQLAlchemy 模型
  • 效能雖不及 C/C++ 引擎,但中小型專案足夠

安裝與配置

flask/bin/pip install Flask-WhooshAlchemy

在 config.py 指定索引儲存路徑:

WHOOSH_BASE = os.path.join(basedir, 'search.db')

模型標記可搜尋欄位

在 models.py 的 Post 類別加入 __searchable__ 並初始化索引:

class Post(db.Model):
    __searchable__ = ['body']
    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.String(140))
    timestamp = db.Column(db.DateTime)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))

    def __repr__(self):
        return '<Post %r>' % self.body

import flask.ext.whooshalchemy as whooshalchemy
whooshalchemy.whoosh_index(app, Post)

現有資料需重建索引:刪除舊貼文並重新新增,或撰寫腳本重建。

搜尋語法測試

>>> Post.query.whoosh_search('post').all()
[<Post 'my second post'>, <Post 'my first post'>, <Post 'my third and last post'>]
>>> Post.query.whoosh_search('second OR last').all()
[<Post 'my second post'>, <Post 'my third and last post'>]

Whoosh 支援布林運算子、欄位限定、通配符等豐富查詢語法。

整合至應用程式

1. 設定最大回傳筆數

MAX_SEARCH_RESULTS = 50

2. 搜尋表單與導覽列整合

class SearchForm(Form):
    search = TextField('search', validators=[Required()])

在 before_request 建立表單實例存入 g.search_form,base.html 導覽列內嵌表單:

<form action="{{ url_for('search') }}" method="post">
    {{ g.search_form.hidden_tag() }}
    {{ g.search_form.search(size=20) }}
    <input type="submit" value="Search">
</form>

3. 搜尋視圖與結果頁面

@app.route('/search', methods=['POST'])
@login_required
def search():
    if not g.search_form.validate_on_submit():
        return redirect(url_for('index'))
    return redirect(url_for('search_results', query=g.search_form.search.data))

@app.route('/search_results/<query>')
@login_required
def search_results(query):
    results = Post.query.whoosh_search(query, MAX_SEARCH_RESULTS).all()
    return render_template('search_results.html', query=query, results=results)

採 POST-Redirect-GET 避免重新整理重複送出。結果頁面重複使用 post.html 子模板。

完成整合後,使用者即可在導覽列輸入關鍵字搜尋全站貼文內容。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved