.search() now works differently for FTS4 v.s. FTS5

This commit is contained in:
Simon Willison 2020-11-05 10:01:58 -08:00
commit 7c22a64fb6
2 changed files with 43 additions and 42 deletions

View file

@ -1326,51 +1326,52 @@ class Table(Queryable):
assert fts_table, "Full-text search is not configured for table '{}'".format(
self.name
)
return textwrap.dedent(
"""
with {original} as (
select
rowid,
{columns}
from [{dbtable}]
)
select
{original}.*,
[{fts}].rank as {rank}
from
[{original}]
join [{fts}] on [{original}].rowid = [{fts}].rowid
where
[{fts}] match :query
order by
{order}
{limit}
""".format(
dbtable=self.name,
original=original,
columns=columns_sql,
rank=rank,
fts=fts_table,
order=order or "{} desc".format(rank),
limit="limit {}".format(limit) if limit else "",
if self.db[fts_table].virtual_table_using == "FTS5":
sql = textwrap.dedent(
"""
with {original} as (
select
rowid,
{columns}
from [{dbtable}]
)
select
{original}.*,
[{fts}].rank as {rank}
from
[{original}]
join [{fts}] on [{original}].rowid = [{fts}].rowid
where
[{fts}] match :query
order by
{order}
{limit}
"""
).strip()
else:
if order == rank or order is None:
order = "rowid"
sql = textwrap.dedent(
"""
select * from "{dbtable}" where rowid in (
select rowid from [{fts}]
where [{fts}] match :query
)
order by {order}
"""
).strip()
return sql.format(
dbtable=self.name,
original=original,
columns=columns_sql,
rank=rank,
fts=fts_table,
order=order or "{} desc".format(rank),
limit="limit {}".format(limit) if limit else "",
).strip()
def search(self, q):
sql = (
textwrap.dedent(
"""
select * from "{table}" where rowid in (
select rowid from [{table}_fts]
where [{table}_fts] match :search
)
order by rowid
"""
)
.strip()
.format(table=self.name)
)
return self.db.execute(sql, (q,)).fetchall()
def search(self, q, order=None):
return self.db.execute(self.search_sql(order=order), {"query": q}).fetchall()
def value_or_default(self, key, value):
return self._defaults[key] if value is DEFAULT else value

View file

@ -112,7 +112,7 @@ def test_fts_tokenize(fresh_db):
tokenize="porter",
)
assert [("racoons are biting trash pandas", "USA", "bar")] == table.search(
"bite"
"bite", order="rowid"
)