Improve search negation logic

Only dashes at the start of terms and outside of quotes are now
interpreted as negation.

Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
Roberto Rosario
2019-06-08 20:47:20 -04:00
parent 6f6ddfbc82
commit 74f333d16c
4 changed files with 74 additions and 34 deletions

View File

@@ -283,7 +283,7 @@
* Add support for Google Fonts dependencies.
* Add support for patchin dependency files using rewriting rules.
* Allow searching documents by UUID.
* Improve search negation logic.
3.1.11 (2019-04-XX)
===================

View File

@@ -711,6 +711,8 @@ Other changes
- Add support for Google Fonts dependencies.
- Add support for patchin dependency files using rewriting rules.
- Allow searching documents by UUID.
- Improve search negation logic. Only dashes at the start of terms and
outside of quotes are now interpreted as negation.
Removals

View File

@@ -255,47 +255,66 @@ class SearchTermCollection(object):
self.terms = []
for letter in text:
if not inside_quotes and letter == TERM_NEGATION_CHARACTER:
negated = True
if letter in TERM_QUOTES:
if inside_quotes:
if term_letters:
term_string = ''.join(term_letters)
negated = False
if term_string.startswith(TERM_NEGATION_CHARACTER):
term_string = term_string[1:]
negated = True
self.terms.append(
SearchTerm(
is_meta=False, negated=negated,
string=term_string
)
)
negated = False
term_letters = []
inside_quotes = not inside_quotes
else:
if letter in TERM_QUOTES:
if inside_quotes:
if term_letters:
self.terms.append(
SearchTerm(
is_meta=False, negated=negated,
string=''.join(term_letters)
)
)
negated = False
term_letters = []
if not inside_quotes and letter == TERM_SPACE_CHARACTER:
if term_letters:
term_string = ''.join(term_letters)
if term_string in TERM_OPERATIONS:
is_meta = True
else:
is_meta = False
inside_quotes = not inside_quotes
print("NEW TERM", ''.join(term_letters))
if is_meta:
negated = False
else:
negated = False
if term_string.startswith(TERM_NEGATION_CHARACTER):
term_string = term_string[1:]
negated = True
self.terms.append(
SearchTerm(
is_meta=is_meta, negated=negated,
string=term_string
)
)
negated = False
term_letters = []
else:
if not inside_quotes and letter == TERM_SPACE_CHARACTER:
if term_letters:
term_string = ''.join(term_letters)
if term_string in TERM_OPERATIONS:
is_meta = True
else:
is_meta = False
self.terms.append(
SearchTerm(
is_meta=is_meta, negated=negated,
string=term_string
)
)
negated = False
term_letters = []
else:
term_letters.append(letter)
term_letters.append(letter)
if term_letters:
term_string = ''.join(term_letters)
negated = False
if term_string.startswith(TERM_NEGATION_CHARACTER):
term_string = term_string[1:]
negated = True
self.terms.append(
SearchTerm(
is_meta=False, negated=negated,
string=''.join(term_letters)
string=term_string
)
)

View File

@@ -1,5 +1,7 @@
from __future__ import unicode_literals
from django.utils.encoding import force_text
from mayan.apps.common.tests import BaseTestCase
from mayan.apps.documents.permissions import permission_document_view
from mayan.apps.documents.search import document_search
@@ -139,3 +141,20 @@ class DocumentSearchTestCase(DocumentTestMixin, BaseTestCase):
{'label': '-non_valid -second'}, user=self._test_case_user
)
self.assertEqual(queryset.count(), 0)
def test_search_with_dashed_content(self):
self.upload_document(label='second-document')
self.grant_access(
obj=self.test_document, permission=permission_document_view
)
queryset = document_search.search(
{'label': '-second-document'}, user=self._test_case_user
)
self.assertEqual(queryset.count(), 0)
queryset = document_search.search(
{'label': '-"second-document"'}, user=self._test_case_user
)
self.assertEqual(queryset.count(), 0)