-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathviews.py
54 lines (42 loc) · 1.66 KB
/
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
from django.shortcuts import render
from django.db.models.expressions import RawSQL
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from todo.models import TodoItem, TodoItemSerializer
class TodoItemViewSet(viewsets.ModelViewSet):
"""TODO items controller."""
queryset = TodoItem.objects.all()
serializer_class = TodoItemSerializer
@action(detail=False, methods=["get"])
def search(self, request):
"""
Search the TODO list by embedding similarity.
"""
query = request.query_params.get("q")
completed = request.query_params.get("completed")
limit = request.query_params.get("limit")
if limit:
limit = int(limit)
if completed:
completed = completed.lower() == "true"
else:
completed = False
if query:
results = TodoItem.objects.annotate(
# Use cosine similarty to find closest matches by their linguistic meaning
similarity=RawSQL(
"pgml.embed('intfloat/e5-small', %s)::vector(384) <=> embedding",
[query],
)
).order_by("similarity")
if completed:
results = results.filter(completed=completed)
if limit:
results = results[:limit]
# If you want to see the query that is executed, uncomment the following line.
# print(results.query)
serializer = TodoItemSerializer(results, many=True)
return Response(serializer.data)
else:
return Response([])