Repository: dag-hammarskjold-library/dlx

Issue:
Revert fielded regex search to case-sensitive
Fielded regex searches mistakenly became case-insensitive at some point

Discussion:

Solution patch:
diff --git a/dlx/marc/query.py b/dlx/marc/query.py
index ec80b969..e03499cf 100644
--- a/dlx/marc/query.py
+++ b/dlx/marc/query.py
@@ -130,7 +130,13 @@ def parse(token, modifier=None):
 
                 # regex
                 if isinstance(value, Regex):
-                    matches = DB.handle[f'_index_{tag}'].find({'subfields.value': value})
+                    if isinstance(value, WildcardRegex):
+                        new_pattern = Tokenizer.scrub(re.sub(r'\^', ' ', value.pattern))  # pseudo index text field starts with a space
+                        matches = DB.handle[f'_index_{tag}'].find({'text': Regex(new_pattern)})
+                    else:
+                        #matches = DB.handle[f'_index_{tag}'].find({'subfields.value': value})
+                        return Condition(tag, {code: value}, modifier=modifier, record_type=self.record_type)
+
                     matched_subfield_values = []
 
                     for m in matches:
@@ -185,7 +191,7 @@ def parse(token, modifier=None):
                     raise InvalidQueryString(f'Text search "{value}" has too many hits on field "{tag}". Try narrowing the search')
                 
                 if modifier == 'not':
-                    q = {f'{tag}': {'$elemMatch': {'subfields': {'$not': {'$elemMatch': {'code': code, 'value': {'$in': matched_subfield_values}}}}}}}
+                    q = {f'{tag}': {'$not': {'$elemMatch': {'subfields': {'$elemMatch': {'code': code, 'value': {'$in': matched_subfield_values}}}}}}}
                 else:
                     q = {f'{tag}.subfields': {'$elemMatch': {'code': code, 'value': {'$in': matched_subfield_values}}}}
 
@@ -243,7 +249,13 @@ def parse(token, modifier=None):
 
                 # regex
                 if isinstance(value, Regex):
-                    matches = DB.handle[f'_index_{tag}'].find({'subfields.value': value})
+                    if isinstance(value, WildcardRegex):
+                        new_pattern = Tokenizer.scrub(re.sub(r'\^', ' ', value.pattern)) # pseudo index text field starts with a space
+                        matches = DB.handle[f'_index_{tag}'].find({'text': Regex(new_pattern)})
+                    else:
+                        #matches = DB.handle[f'_index_{tag}'].find({'subfields.value': value})
+                        return TagOnly(tag, value, modifier=modifier, record_type=self.record_type)
+                    
                     matched_subfield_values = []
                     
                     for m in matches:
@@ -297,7 +309,7 @@ def parse(token, modifier=None):
                     raise InvalidQueryString(f'Text search "{value}" has too many hits on field "{tag}". Try narrowing the search')
 
                 if modifier == 'not':
-                    q = {f'{tag}': {'$elemMatch': {'subfields': {'$not': {'$elemMatch': {'value': {'$in': matched_subfield_values}}}}}}}
+                    q = {f'{tag}': {'$not': {'$elemMatch': {'subfields': {'$elemMatch': {'value': {'$in': matched_subfield_values}}}}}}}
                 else:
                     q = {f'{tag}.subfields.value': {'$in': matched_subfield_values}}
 
@@ -411,7 +423,8 @@ def parse(token, modifier=None):
                     # regex
                     if isinstance(value, Regex):
                         if isinstance(value, WildcardRegex):
-                            q = {'text': value}
+                            new_pattern = Tokenizer.scrub(re.sub(r'\^', ' ', value.pattern)) # pseudo index text field starts with a space
+                            q = {'text': Regex(new_pattern)}
                         else:
                             q = {'_id': value}
                     # text
diff --git a/setup.py b/setup.py
index c44a8450..ce16a629 100644
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,4 @@
-version = '1.4.14'
+version = '1.4.15'
 
 import sys
 from setuptools import setup, find_packages


Test patch:
diff --git a/tests/test_marc.py b/tests/test_marc.py
index f3538447..2eda5447 100644
--- a/tests/test_marc.py
+++ b/tests/test_marc.py
@@ -378,9 +378,9 @@ def test_querystring(db):
     assert len(list(BibSet.from_query(query.compile()))) == 0
 
     # NOT with text
-    bib.set('246', 'a', 'Second alt title', address='+').commit()
+    bib.set('246', 'a', 'Edited alt title', address='+').commit()
     query = Query.from_string(f'NOT 246:New title', record_type='bib')
-    assert len(list(BibSet.from_query(query.compile()))) == 1
+    assert len(list(BibSet.from_query(query.compile()))) == 0
 
     # NOT xref
     query = Query.from_string(f'NOT xref:1', record_type='bib')