Skip to content

Commit

Permalink
library.py: search() - fts5 search improvement for keywords shorter t…
Browse files Browse the repository at this point in the history
…han 3 unicode characters

FTS5 'match' only evaluates substrings longer than 3 unicode characters, searching for
shorter substrings results in no matches being returned.

Fixes an issue where attempting to search for substrings shorter than 3 characters was
resulting in empty search results.

Add "AND description LIKE '%SUBSTRING%'" terms for each substring shorter than 3 characters.
  • Loading branch information
chmorgan committed Apr 25, 2024
1 parent c37d15e commit 6d2d4fa
Showing 1 changed file with 23 additions and 3 deletions.
26 changes: 23 additions & 3 deletions library.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,33 @@ def search(self, parameters):
query = f"SELECT {s} FROM parts WHERE "

match_chunks = []
like_chunks = []

query_chunks = []

# Build 'match_chunks' and 'like_chunks' arrays
#
# FTS5 (https://www.sqlite.org/fts5.html) has a substring limit of
# at least 3 characters.
# 'Substrings consisting of fewer than 3 unicode characters do not
# match any rows when used with a full-text query'
#
# However, they will still match with a LIKE.
#
# So extract out the <3 character strings and add a 'LIKE' term
# for each of those.
if parameters["keyword"] != "":
keywords = parameters["keyword"].split(" ")
keywords_intermediate = []
for w in keywords:
# skip over empty keywords
if w != "":
kw = f'"{w}"'
keywords_intermediate.append(kw)
if len(w) < 3: # LIKE entry
kw = f"AND description LIKE '%{w}%'"
like_chunks.append(kw)
else: # MATCH entry
kw = f'"{w}"'
keywords_intermediate.append(kw)
keywords_entry = " AND ".join(keywords_intermediate)
match_chunks.append(f"{keywords_entry}")

Expand Down Expand Up @@ -171,14 +188,17 @@ def search(self, parameters):
if parameters["stock"]:
query_chunks.append('"Stock" > "0"')

if not match_chunks and not query_chunks:
if not match_chunks and not like_chunks and not query_chunks:
return []

if match_chunks:
query += "parts MATCH '"
query += " AND ".join(match_chunks)
query += "'"

if like_chunks:
query += " ".join(like_chunks)

if query_chunks:
if match_chunks:
query += " AND "
Expand Down

0 comments on commit 6d2d4fa

Please sign in to comment.