From 4f7396d059aa6a143b1166abf695fcfbdc800bdd Mon Sep 17 00:00:00 2001 From: Miguel Date: Tue, 11 Nov 2014 08:22:11 +0300 Subject: [PATCH] Forum search added and some modifications done. --- fts.sql | 74 ++++++++++++++++++++++++++++++++++++++++++ static/search-help.rst | 35 ++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 fts.sql create mode 100644 static/search-help.rst diff --git a/fts.sql b/fts.sql new file mode 100644 index 0000000..ab49d31 --- /dev/null +++ b/fts.sql @@ -0,0 +1,74 @@ +-- selects just threads, +-- those where title doesn't coinside with some of its posts' titles +-- by now selects only the threads title (no post snippet) +SELECT + thread_id, + snippet(thread_fts, '', '', '...') AS thread, + 0 AS post_id, + '' AS header, + '' AS content, + person.name AS author, + cdate, + author_id, + person.email AS email, + 0 AS what + FROM ( + SELECT + thread_fts.id AS thread_id, + post.id AS post_id, + post.creation AS cdate, + MIN(post.creation) AS cdate, + post.author AS author_id + FROM thread_fts + JOIN post ON post.thread=thread_id + WHERE thread_fts MATCH ? + GROUP BY thread_id, post_id + HAVING thread_id NOT IN ( + SELECT thread + FROM post_fts JOIN post USING(id) + WHERE post_fts MATCH ? + ) + LIMIT ? OFFSET (? - 1) * ? + ) + JOIN thread_fts ON thread_fts.id=thread_id + JOIN person ON person.id=author_id + WHERE thread_fts MATCH ? +UNION +-- the main query, selects posts +SELECT + thread.id AS thread_id, + thread.name AS thread, + post.id AS post_id, + CASE what WHEN 1 + THEN snippet(post_fts, '', '', '...', what) + ELSE post_fts.header END AS header, + CASE what WHEN 2 + THEN snippet(post_fts, '', '', '...', what, -45) + ELSE SUBSTR(post_fts.content, 1, 200) END AS content, + person.name AS author, + cdate, + post.author AS author_id, + person.email AS email, + what + FROM post_fts JOIN ( + -- inner query, selects ids of matching posts, orders and limits them, + -- so snippets only for limited count of posts are created (in outer query) + SELECT id, post.creation AS cdate, thread, 1 AS what, post.author AS author + FROM post_fts JOIN post USING(id) + WHERE post_fts.header MATCH ? + GROUP BY post.header + HAVING SUBSTR(post.header,1,3)<>'Re:' + UNION + SELECT id, post.creation AS cdate, thread, 2 AS what, post.author AS author + FROM post_fts JOIN post USING(id) + WHERE post_fts.content MATCH ? + ORDER BY what, cdate DESC + LIMIT ? OFFSET (? - 1) * ? + ) AS post USING(id) + JOIN thread ON thread.id=thread + JOIN person ON person.id=author + WHERE post_fts MATCH ? +ORDER BY what ASC, cdate DESC +LIMIT 300 -- hardcoded limit just in case +; + diff --git a/static/search-help.rst b/static/search-help.rst new file mode 100644 index 0000000..8e7fc80 --- /dev/null +++ b/static/search-help.rst @@ -0,0 +1,35 @@ +Full-text search for Nim forum +============================== + +Syntax (using *SQLite* dll compiled without *Enhanced Query Syntax* support): +----------------------------------------------------------------------------- + +- Only alphanumeric characters are searched. +- Only full words and words beginnings (e.g. ``Nim*`` for both ``Nimrod`` and ``Nim``) are searched +- All words are joined with implicit **AND** operator; there's no explicit one +- There's explicit **OR** operator (upper-case) and it has higher priority +- Words can be prepended with **-** to be excluded from search +- No parentheses support +- Quotes for phrases search, e.g. ``"programming language"`` +- Distances between words/phrases can be specified putting ``NEAR`` or ``NEAR/some_number`` between them + +Syntax - differences in *Enhanced Query Syntax* (should be enabled in *SQLite* dll): +------------------------------------------------------------------------------------ + +- **AND** and **NOT** logical operators available +- Precedence of operators is, from highest to lowest: **NOT**, **AND**, **OR** +- Parentheses for grouping are supported + +Where search is performed: +-------------------------- + +- **Threads' titles** - these results are outputed first +- **Posts' titles** - middle precedence +- **Posts' contents** - the latest + +How results are shown: +---------------------- + +- All results are ordered by date (posts' edits don't affect) +- Matched tokens in text are marked (bold or dotted underline) +- Threads title is the link to the thread and posts title is the link to the post