Repository: internetarchive/openlibrary

Issue:
Bad matches in works Mass tagging system
I was trying to add subject "Comedy" to the works and these are the first matches I get 
![зображення](https://github.com/internetarchive/openlibrary/assets/58372007/47771127-28bc-4373-8945-e483dba97c00)
And when I try to manually search for the exact match there are many more subjects with word "coming" that have less works than the actual "Comedy". I think the exact matches should be the first one in the list or at least be boosted.

### Evidence / Screenshot (if possible)

### Relevant url?
<!-- `https://openlibrary.org/...` -->

### Steps to Reproduce
<!-- What steps caused you to find the bug? -->
1. Go to ...
2. Do ...

<!-- What actually happened after these steps? What did you expect to happen? -->
* Actual:
* Expected:

### Details

- **Logged in (Y/N)?**
- **Browser type/version?**
- **Operating system?**
- **Environment (prod/dev/local)?** prod
<!-- If not sure, put prod -->

### Proposal & Constraints
<!-- What is the proposed solution / implementation? Is there a precedent of this approach succeeding elsewhere? -->

### Related files
<!-- Files related to this issue; this is super useful for new contributors who might want to help! If you're not sure, leave this blank; a maintainer will add them. -->

### Stakeholders
<!-- @ tag stakeholders of this bug -->



Discussion:

Resolving patch:
diff --git a/openlibrary/plugins/openlibrary/bulk_tag.py b/openlibrary/plugins/openlibrary/bulk_tag.py
--- a/openlibrary/plugins/openlibrary/bulk_tag.py
+++ b/openlibrary/plugins/openlibrary/bulk_tag.py
@@ -5,31 +5,16 @@
 import json
 
 
-class tags_partials(delegate.page):
-    path = "/tags/partials"
-    encoding = "json"
-
-    def GET(self):
-        i = web.input(key=None)
-
-        works = i.work_ids
-
-        tagging_menu = render_template('subjects/tagging_menu', works)
-
-        partials = {
-            'tagging_menu': str(tagging_menu),
-        }
-
-        return delegate.RawText(json.dumps(partials))
-
-
 class bulk_tag_works(delegate.page):
     path = "/tags/bulk_tag_works"
 
     def POST(self):
-        i = web.input(work_ids='', tag_subjects='{}')
+        i = web.input(work_ids='', tags_to_add='', tags_to_remove='')
+
         works = i.work_ids.split(',')
-        incoming_subjects = json.loads(i.tag_subjects)
+        tags_to_add = json.loads(i.tags_to_add or '{}')
+        tags_to_remove = json.loads(i.tags_to_remove or '{}')
+
         docs_to_update = []
 
         for work in works:
@@ -40,13 +25,22 @@ def POST(self):
                 'subject_places': uniq(w.get('subject_places', '')),
                 'subject_times': uniq(w.get('subject_times', '')),
             }
-            for subject_type, subject_list in incoming_subjects.items():
-                if subject_list:
+            for subject_type, add_list in tags_to_add.items():
+                if add_list:
                     current_subjects[subject_type] = uniq(  # dedupe incoming subjects
-                        current_subjects[subject_type] + subject_list
+                        current_subjects[subject_type] + add_list
                     )
                     w[subject_type] = current_subjects[subject_type]
 
+            for subject_type, remove_list in tags_to_remove.items():
+                if remove_list:
+                    current_subjects[subject_type] = [
+                        item
+                        for item in current_subjects[subject_type]
+                        if item not in remove_list
+                    ]
+                    w[subject_type] = current_subjects[subject_type]
+
             docs_to_update.append(
                 w.dict()
             )  # need to convert class to raw dict in order for save_many to work


Test patch: