Flask - SQLAlchemy全文搜索

时间:2016-12-06 17:00:40

标签: flask flask-sqlalchemy whoosh

我正在尝试建立一个小型在线工厂数据库,并希望整合一个搜索引擎。我正在使用Flask构建我的应用程序,并且我使用SQLAlchemy和pymysql将应用程序连接到MySQL数据库。我一直在摆弄Flask-WhooshAlchemy,到目前为止我没有运气。我想要的是搜索,如果用户搜索特定的植物,它将转到植物信息页面或返回类似物种的结果。例如,如果他们要搜索'Carex utriculata',它会将它们直接带到'Carex utriculata'的物种信息页面。但是,如果他们搜索“Carex”,他们会得到一个列出所有类似物种的结果页面,因此可能会有一个类似'Carex aquatilis''Carex keloggii''Carex utriculata'的列表。

在我的尝试中,到目前为止似乎尝试了搜索,但结果显示了我数据库中的所有植物,而不仅仅是输入到搜索中的植物。我甚至没有试过让搜索直接进入单个工厂的页面,如果它与搜索完全匹配,因为我一直坚持让搜索工作。我正在使用Python 3.5。这是我的代码。

初始化的.py

import pymysql.cursors
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import flask_whooshalchemy as whooshalchemy


app = Flask(__name__)


app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:passwrd@localhost/restorationplantdb'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['WHOOSE_BASE'] = 'results'


db = SQLAlchemy(app)

class SPInfo(db.Model):
    __tablename__ = 'speciesinfo'
    __searchable__ = ['NRCS_Species', 'NRCS_CommonName']
    speciesinfo_id = db.Column(db.Integer,primary_key=True)
    ID = db.Column(db.Integer)
    MTNHP_Species = db.Column(db.String(45))
    NRCS_Species = db.Column(db.String(45))
    NRCS_CommonName = db.Column(db.String(45))
    Synonyms = db.Column(db.Text)
    Sp_Stratum = db.Column(db.String(12))
    Origin = db.Column(db.String(25))
    Duration = db.Column(db.String(25))
    Habitat = db.Column(db.Text)
    Elevation = db.Column(db.Text)


whooshalchemy.whoosh_index(app, SPInfo)

import RestorationPlantDB.views

views.py

from flask import render_template, url_for, redirect, session, request
from datetime import datetime
from RestorationPlantDB import app
from RestorationPlantDB import db
from RestorationPlantDB import SPInfo



@app.route('/search', methods = ['GET','POST'])
def search():
    results = SPInfo.query.all()
    return render_template('search.html', results=results)

@app.route('/results')
def results():
    results = SPInfo.query.whoosh_search(request.args.get('query')).all()
    return render_template('search.html', results=results)

search.html

{% extends "layout.html" %}

{% block content %}


{% for result in results %}
<p>{{ result.NRCS_Species }} - {{ result.NRCS_CommonName }}</p>
{% endfor %}



<div class="col-sm-3 col-sm-offset-1 blog sidebar">
    <div class="sidebar-module sidebar-module-insert">
        <h4>Search</h4>
        <form class="form-inline" method="GET" action="search">
            <div class="form-group">
                <label for="query">Name</label>
                <input type="text" class="form-control" name="query" id="query" />
            </div>
            <button type="submit" class="btn btn-primary">Search</button>
        </form>
    </div>
</div>


{% endblock %}

1 个答案:

答案 0 :(得分:0)

你正在做的就是查询一切,这就是你得到一切的原因。您在@app.route('/search', methods = ['GET','POST']) def search(results=None): if request.method == 'POST': results = SPInfo.query.whoosh_search(request.form.get('query')).all() return render_template('search.html', results=results) 下过滤了查询,但表单并未转到此处。不要把它们分开,你可以轻松地做到这一点:

/results

并完全删除from sqlalchemy import func @app.route('/search', methods = ['GET','POST']) def search(results=None): if request.method == 'POST': keywords = request.form.get('query') unique_result = SPInfo.query.filter(func.lower(SPInfo.NRCS_Species) == func.lower(keywords)).first() or SPInfo.query.filter(func.lower(SPInfo.NRCS_CommonName) == func.lower(keywords)).first() if unique_result: #insert return redirect() to specific page using unique_result here results = SPInfo.query.whoosh_search(keywords).all() return render_template('search.html', results=results) 。接下来,您需要实现重定向到完全匹配。我会将其添加到上面的代码中:

unique_result = SPInfo.query.filter_by(NRCS_Species=keywords).first() or SPInfo.query.filter_by(NRCS_CommonName=keywords).first()

通常我会做的就是:

{% if results %}
    {% for result in results %}
        <p>{{ result.NRCS_Species }} - {{ result.NRCS_CommonName }}</p>
    {% endfor %}
{% endif %}

但我认为你希望它不区分大小写。如果你没有,请用这个替换查询。

我还将重定向留空,因为我不知道您的物种页面的路线是什么,但它不应该很难弄明白。

编辑

更改了函数定义,需要将一个小的更改添加到模板中,如下所示:

public void addStaff(String id, String name) {
this.id = id;
this.name = name;
Clerk clerk = new Clerk(id, name);
this.yourArrayList.add(clerk);
}