From f8e3e3c36af100c59784b7bb95b08f75afcfcc80 Mon Sep 17 00:00:00 2001
From: TheJoeCoder <joe@radialbog9.uk>
Date: Sat, 19 Apr 2025 23:19:01 +0100
Subject: [PATCH] Implement the same fuzzy search system in OPAC

---
 librarian/views.py |  4 +---
 opac/views.py      | 30 ++++++++++++++++++++++++++++--
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/librarian/views.py b/librarian/views.py
index 4e35d4b..00760b8 100644
--- a/librarian/views.py
+++ b/librarian/views.py
@@ -634,12 +634,10 @@ def search_all(request):
         *[Q("term", **{f: query}) for f in term_fields],
     ])
 
-    print(query_conditions)
-
     qur = srch.query(query_conditions).execute()
-    print(qur.to_dict())
 
     # Get results
+    # TODO this does 1 query per result, which is inefficient.
     results = []
     for hit in qur:
         if hit.meta.index == "books":
diff --git a/opac/views.py b/opac/views.py
index af6760f..07cb9a2 100644
--- a/opac/views.py
+++ b/opac/views.py
@@ -40,10 +40,36 @@ def search_all(request):
     """
     query = request.GET.get("q")
 
-    fields = ["first_name", "last_name", "title", "description", "isbn10", "isbn13"]
+    fuzzy_search_fields = [
+        "first_name",
+        "last_name",
+        "title",
+        "description"
+    ]
 
+    term_fields = []
+    if query.isdigit():
+        # If the query is a number, search for ISBNs and years
+        term_fields += [
+            "published_year",
+            "isbn10",
+            "isbn13",
+        ]
+
+    # Create the search object
     search = Search(index=["books", "authors"])
-    qry = search.query("multi_match", query=query, fields=fields).execute()
+
+    # Build the query from the fields
+    query_conditions = Q("bool", should=[
+        *[Q("fuzzy", **{f: query}) for f in fuzzy_search_fields],
+        *[Q("term", **{f: query}) for f in term_fields],
+    ])
+
+    # Query using the search object
+    qry = search.query(query_conditions).execute()
+
+    # Gather results
+    # TODO this does 1 query per result, which is inefficient.
     results = []
     for result in qry:
         if result.meta.index == "books":
-- 
GitLab