1
0
mirror of https://github.com/janeczku/calibre-web synced 2024-11-18 07:44:54 +00:00

fuzzy matching for all categories but cc

This commit is contained in:
Daniel 2023-04-29 17:11:52 +02:00
parent d13d4653be
commit 8e8c9a14a8
2 changed files with 26 additions and 14 deletions

View File

@ -50,7 +50,10 @@ from . import logger, ub, isoLanguages
from .pagination import Pagination from .pagination import Pagination
from weakref import WeakSet from weakref import WeakSet
from fuzzywuzzy.fuzz import ratio from thefuzz.fuzz import partial_ratio
# %-level, 100 means exact match
FUZZY_SEARCH_ACCURACY=80
log = logger.create() log = logger.create()
@ -886,7 +889,7 @@ class CalibreDB:
def search_query(self, term, config, *join): def search_query(self, term, config, *join):
term.strip().lower() term.strip().lower()
self.session.connection().connection.connection.create_function("lower", 1, lcase) self.session.connection().connection.connection.create_function("lower", 1, lcase)
self.session.connection().connection.connection.create_function("ratio", 2, ratio) self.session.connection().connection.connection.create_function("partial_ratio", 2, partial_ratio)
q = list() q = list()
#splits search term into single words #splits search term into single words
words = re.split("[, ]+", term) words = re.split("[, ]+", term)
@ -894,7 +897,7 @@ class CalibreDB:
words.sort(key=len,reverse=True) words.sort(key=len,reverse=True)
#search authors for match #search authors for match
for word in words: for word in words:
q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + word + "%"))) q.append(Books.authors.any(func.partial_ratio(func.lower(Authors.name),word)>=FUZZY_SEARCH_ACCURACY))
query = self.generate_linked_query(config.config_read_column, Books) query = self.generate_linked_query(config.config_read_column, Books)
if len(join) == 6: if len(join) == 6:
@ -917,18 +920,19 @@ class CalibreDB:
# filter out multiple languages and archived books, # filter out multiple languages and archived books,
results=query.filter(self.common_filters(True)) results=query.filter(self.common_filters(True))
# for word in words: #search tags, series and titles, also add author queries
# filter_expression=[ for word in words:
# Books.tags.any(func.lower(Tags.name).ilike("%" + word + "%")), filter_expression=[
# Books.series.any(func.lower(Series.name).ilike("%" + word + "%")), Books.tags.any(func.partial_ratio(func.lower(Tags.name),word)>=FUZZY_SEARCH_ACCURACY),
# #change to or_ to allow mix of title and author in query term Books.series.any(func.partial_ratio(func.lower(Series.name),word)>=FUZZY_SEARCH_ACCURACY),
# Books.authors.any(or_(*q)), #change to or_ to allow mix of title and author in query term
# Books.publishers.any(func.lower(Publishers.name).ilike("%" + word + "%")), Books.authors.any(or_(*q)),
# func.lower(Books.title).ilike("%" + word + "%") Books.publishers.any(func.partial_ratio(func.lower(Publishers.name),word)>=FUZZY_SEARCH_ACCURACY),
# ] func.partial_ratio(func.lower(Books.title),word)>=FUZZY_SEARCH_ACCURACY
# results=results.filter(or_(*filter_expression)) ]
results=results.filter(or_(*filter_expression))
try: return results.filter(func.ratio(Books.title,term)>80) try: return results
except Exception: except Exception:
print(traceback.format_exc()) print(traceback.format_exc())

View File

@ -18,3 +18,11 @@ flask-wtf>=0.14.2,<1.2.0
chardet>=3.0.0,<4.1.0 chardet>=3.0.0,<4.1.0
advocate>=1.0.0,<1.1.0 advocate>=1.0.0,<1.1.0
Flask-Limiter>=2.3.0,<3.4.0 Flask-Limiter>=2.3.0,<3.4.0
thefuzz~=0.19.0
MarkupSafe~=2.1.1
Jinja2~=3.1.2
Levenshtein~=0.21.0
greenlet~=1.1.3
cryptography~=38.0.1
setuptools~=57.0.0