Skip to content

Commit

Permalink
feat: tokenize search
Browse files Browse the repository at this point in the history
  • Loading branch information
b1rger committed Dec 14, 2023
1 parent cda5f09 commit 6d47d66
Showing 1 changed file with 38 additions and 1 deletion.
39 changes: 38 additions & 1 deletion apis_ontology/filters.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,42 @@
import logging
import itertools
import re

from django.db import models

PATTERN = re.compile(r'''((?:[^ "']|"[^"]*"|'[^']*')+)''')

logger = logging.getLogger(__name__)


def valuetosearchtype(value):
if value.strip('"') == value:
return "__unaccent__icontains", value
return "__exact", value.strip('"')


def tokenize(value):
tokens = PATTERN.split(value)
tokens = list(filter(str.strip, tokens))
return list(map(valuetosearchtype, tokens))


def name_first_name_filter(queryset, name, value):
return queryset.filter(models.Q(name__unaccent__icontains=value) | models.Q(first_name__unaccent__icontains=value))
tokens = tokenize(value)
searchfields = ["first_name", "name"]

q = models.Q()
if len(tokens) > 1:
for combination in itertools.permutations(tokens, len(searchfields)):
q_and = models.Q()
mapping = [{field + searchtype: value} for field, (searchtype, value) in zip(searchfields, combination)]
for query in mapping:
q_and &= models.Q(**query)
q |= q_and
else:
for searchfield in searchfields:
mapping = [{searchfield + searchtype: value} for searchtype, value in tokens]
for query in mapping:
q |= models.Q(**query)
logger.debug(q)
return queryset.filter(q)

0 comments on commit 6d47d66

Please sign in to comment.