search: Move from hand-crafted SQL to ORM

This commit is contained in:
Eragon 2023-08-08 23:10:06 +02:00
parent 2d7271723f
commit 621cd40659
Signed by: Eragon
GPG Key ID: 087126EBFC725006
2 changed files with 29 additions and 16 deletions

View File

@ -1,31 +1,41 @@
from app import app, db
from app.forms.search import AdvancedSearchForm, SearchForm
from app.models.post import Post
from app.models.comment import Comment
from app.models.topic import Topic
from app.models.forum import Forum
from app.utils.render import render
from sqlalchemy import text
from sqlalchemy import text, func
from flask import request
def websearch_to_tsquery_multilang(search):
return func.websearch_to_tsquery('french', search)
def to_tsvector_multilang(text):
return func.to_tsvector('french', text)
@app.route('/rechercher')
def search():
form = AdvancedSearchForm(request.args)
results = list()
if form.validate():
# Topics are sorted first in results
topics = text("""SELECT topic.id, ts_headline(topic.title, query, 'StartSel=<<, StopSel=>>') AS headline, ts_rank_cd(textsearch, query) AS rank, MAX(topic.title)
FROM topic, websearch_to_tsquery_multilang(:keywords) query, to_tsvector_multilang(topic.title) textsearch
WHERE query @@ textsearch
GROUP BY topic.id,query,textsearch
ORDER BY rank DESC;""")
results = list(db.session.execute(topics, {'keywords': '%' + form.q.data + '%'}))
tsquery = websearch_to_tsquery_multilang(form.q.data)
results = db.session.query(Topic).where(
to_tsvector_multilang(Topic.title).bool_op('@@')(tsquery)
).group_by(
Topic.id,
Post.id
)
# Comments are less important than topics and programs
forums = text("""SELECT comment.id, ts_headline(comment.text, query, 'StartSel=<<, StopSel=>>') AS headline, ts_rank_cd(textsearch, query) AS rank, MAX(topic.title) as title
FROM comment, websearch_to_tsquery_multilang(:keywords) query, to_tsvector_multilang(comment.text) textsearch, topic, program
WHERE query @@ textsearch
AND comment.thread_id = topic.thread_id
GROUP BY comment.id,query,textsearch
ORDER BY rank DESC;""")
results.extend(list(db.session.execute(forums, {'keywords': '%' + form.q.data + '%'})))
print(results)
res = db.session.query(Comment).where(
to_tsvector_multilang(Comment.text).bool_op('@@')(tsquery)
).group_by(
Comment.id,
Post.id
)
results = list(results) + list(res)
return render('search.html', form=form, results=results)

View File

@ -31,7 +31,10 @@
<section class="search-results">
{% for i in results %}
<div>
{{ i.id }} {{ i.title }} {{ rank }}<br>
{{ i.id }} {{ i.title }} {{ i.forum }}<br>
{% if i.forum %}
<a href="{{ url_for('forum_topic', f=i.forum, page=(i , 'fin')) }}">{{ i.title }}</a>
{% endif %}
{{ i.headline }}<br>
</div>
{% endfor %}