Skip to content

Commit

Permalink
Medibase: Drop littletable; instead store as list from ORM's `values_…
Browse files Browse the repository at this point in the history
…list` (#1443)

* custom in memory search

* as tuple

* fix tests

* remove db queryset reference after loading to in-memory

* minor optimization

* remove commented code

* load to in-mem using ORM's `values_list`

* Update care/facility/api/viewsets/prescription.py

Co-authored-by: Aakash Singh <[email protected]>

---------

Co-authored-by: Aakash Singh <[email protected]>
  • Loading branch information
rithviknishad and sainak authored Jul 11, 2023
1 parent f0734f5 commit eb98ba0
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 50 deletions.
50 changes: 20 additions & 30 deletions care/facility/api/viewsets/prescription.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from re import IGNORECASE

from django.shortcuts import get_object_or_404
from django_filters import rest_framework as filters
from drf_spectacular.utils import extend_schema
Expand Down Expand Up @@ -140,36 +138,30 @@ class MedibaseViewSet(ViewSet):
permission_classes = (IsAuthenticated,)

def serailize_data(self, objects):
result = []
for object in objects:
if type(object) == tuple:
object = object[0]
result.append(
{
"id": object.external_id,
"name": object.name,
"type": object.type,
"generic": object.generic,
"company": object.company,
"contents": object.contents,
"cims_class": object.cims_class,
"atc_classification": object.atc_classification,
}
)
return result
return [
{
"id": x[0],
"name": x[1],
"type": x[2],
"generic": x[3],
"company": x[4],
"contents": x[5],
"cims_class": x[6],
"atc_classification": x[7],
}
for x in objects
]

def sort(self, query, results):
exact_matches = []
partial_matches = []

for result in results:
if type(result) == tuple:
result = result[0]
words = result.searchable.lower().split()
for x in results:
words = f"{x[1]} {x[3]} {x[4]}".lower().split()
if query in words:
exact_matches.append(result)
exact_matches.append(x)
else:
partial_matches.append(result)
partial_matches.append(x)

return exact_matches + partial_matches

Expand All @@ -178,10 +170,8 @@ def list(self, request):

queryset = MedibaseMedicineTable

if request.GET.get("query", False):
query = request.GET.get("query").strip().lower()
queryset = queryset.where(
searchable=queryset.re_match(r".*" + query + r".*", IGNORECASE)
)
if query := request.query_params.get("query"):
query = query.strip().lower()
queryset = [x for x in queryset if query in f"{x[1]} {x[3]} {x[4]}".lower()]
queryset = self.sort(query, queryset)
return Response(self.serailize_data(queryset[:15]))
48 changes: 28 additions & 20 deletions care/facility/static_data/medibase.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
from littletable import Table
from django.db.models import CharField, TextField, Value
from django.db.models.functions import Coalesce

from care.facility.models.prescription import MedibaseMedicine

MedibaseMedicineTable = Table("MedibaseMedicine")

medibase_objects = MedibaseMedicine.objects.all()

for obj in medibase_objects:
MedibaseMedicineTable.insert(
{
"id": obj.id,
"external_id": obj.external_id,
"name": obj.name,
"type": obj.type,
"generic": obj.generic or "",
"company": obj.company or "",
"contents": obj.contents or "",
"cims_class": obj.cims_class or "",
"atc_classification": obj.atc_classification or "",
"searchable": f"{obj.name} {obj.generic} {obj.company}",
}
def load_medibase_in_memory():
return (
MedibaseMedicine.objects.all()
.annotate(
generic_pretty=Coalesce("generic", Value(""), output_field=CharField()),
company_pretty=Coalesce("company", Value(""), output_field=CharField()),
contents_pretty=Coalesce("contents", Value(""), output_field=TextField()),
cims_class_pretty=Coalesce(
"cims_class", Value(""), output_field=CharField()
),
atc_classification_pretty=Coalesce(
"atc_classification", Value(""), output_field=TextField()
),
)
.values_list(
"external_id",
"name",
"type",
"generic_pretty",
"company_pretty",
"contents_pretty",
"cims_class_pretty",
"atc_classification_pretty",
)
)

MedibaseMedicineTable.create_index("id", unique=True)
MedibaseMedicineTable.create_search_index("searchable")

MedibaseMedicineTable = load_medibase_in_memory()
2 changes: 2 additions & 0 deletions config/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@
# Apply WSGI middleware here.
# from helloworld.wsgi import HelloWorldApplication
# application = HelloWorldApplication(application)

from care.facility.static_data.medibase import MedibaseMedicineTable # noqa

0 comments on commit eb98ba0

Please sign in to comment.