Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(search): creates a model to capture user queries #4474

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions cl/search/migrations/0035_searchquery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Generated by Django 5.1.1 on 2024-09-19 00:54

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("search", "0034_add_harvard_pdf_to_opinioncluster"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name="SearchQuery",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"date_created",
models.DateTimeField(
auto_now_add=True,
db_index=True,
help_text="The moment when the item was created.",
),
),
(
"date_modified",
models.DateTimeField(
auto_now=True,
db_index=True,
help_text="The last moment when the item was modified. A value in year 1750 indicates the value is unknown",
),
),
(
"get_params",
models.TextField(
help_text="The GET parameters of the search query."
),
),
(
"query_time_ms",
models.IntegerField(
help_text="The time taken to execute the query, in milliseconds."
),
),
(
"hit_cache",
models.BooleanField(
help_text="Whether the query hit the cache or not."
),
),
(
"user",
models.ForeignKey(
blank=True,
help_text="The user who performed this search query.",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="search_queries",
to=settings.AUTH_USER_MODEL,
),
),
],
options={
"abstract": False,
},
),
]
10 changes: 10 additions & 0 deletions cl/search/migrations/0035_searchquery.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
BEGIN;
--
-- Create model SearchQuery
--
CREATE TABLE "search_searchquery" ("id" integer NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, "date_created" timestamp with time zone NOT NULL, "date_modified" timestamp with time zone NOT NULL, "get_params" text NOT NULL, "query_time_ms" integer NOT NULL, "hit_cache" boolean NOT NULL, "user_id" integer NULL);
ALTER TABLE "search_searchquery" ADD CONSTRAINT "search_searchquery_user_id_8918791c_fk_auth_user_id" FOREIGN KEY ("user_id") REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED;
CREATE INDEX "search_searchquery_date_created_89023a7b" ON "search_searchquery" ("date_created");
CREATE INDEX "search_searchquery_date_modified_ec5bc897" ON "search_searchquery" ("date_modified");
CREATE INDEX "search_searchquery_user_id_8918791c" ON "search_searchquery" ("user_id");
COMMIT;
10 changes: 10 additions & 0 deletions cl/search/migrations/0035_searchquery_customers.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
BEGIN;
--
-- Create model SearchQuery
--
CREATE TABLE "search_searchquery" ("id" integer NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, "date_created" timestamp with time zone NOT NULL, "date_modified" timestamp with time zone NOT NULL, "get_params" text NOT NULL, "query_time_ms" integer NOT NULL, "hit_cache" boolean NOT NULL, "user_id" integer NULL);
ALTER TABLE "search_searchquery" ADD CONSTRAINT "search_searchquery_user_id_8918791c_fk_auth_user_id" FOREIGN KEY ("user_id") REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED;
CREATE INDEX "search_searchquery_date_created_89023a7b" ON "search_searchquery" ("date_created");
CREATE INDEX "search_searchquery_date_modified_ec5bc897" ON "search_searchquery" ("date_modified");
CREATE INDEX "search_searchquery_user_id_8918791c" ON "search_searchquery" ("user_id");
COMMIT;
21 changes: 21 additions & 0 deletions cl/search/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import pytz
from asgiref.sync import sync_to_async
from celery.canvas import chain
from django.contrib.auth.models import User
from django.contrib.contenttypes.fields import GenericRelation
from django.contrib.postgres.indexes import HashIndex
from django.core.exceptions import ValidationError
Expand Down Expand Up @@ -233,6 +234,26 @@ class SOURCES:
)


class SearchQuery(AbstractDateTimeModel):
user = models.ForeignKey(
User,
help_text="The user who performed this search query.",
related_name="search_queries",
on_delete=models.SET_NULL,
null=True,
blank=True,
)
get_params = models.TextField(
help_text="The GET parameters of the search query."
)
query_time_ms = models.IntegerField(
help_text="The time taken to execute the query, in milliseconds."
)
hit_cache = models.BooleanField(
help_text="Whether the query hit the cache or not."
)


@pghistory.track(AfterUpdateOrDeleteSnapshot())
class OriginatingCourtInformation(AbstractDateTimeModel):
"""Lower court metadata to associate with appellate cases.
Expand Down
15 changes: 14 additions & 1 deletion cl/search/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,13 @@
UnbalancedQuotesQuery,
)
from cl.search.forms import SearchForm, _clean_form
from cl.search.models import SEARCH_TYPES, Court, Opinion, OpinionCluster
from cl.search.models import (
SEARCH_TYPES,
Court,
Opinion,
OpinionCluster,
SearchQuery,
)
from cl.stats.models import Stat
from cl.stats.utils import tally_stat
from cl.visualizations.models import SCOTUSMap
Expand Down Expand Up @@ -514,6 +520,13 @@ def show_results(request: HttpRequest) -> HttpResponse:
if not is_bot(request):
async_to_sync(tally_stat)("search.results")

# Create and save the SearchQuery object
SearchQuery.objects.create(
get_params=request.GET.urlencode(),
query_time_ms=render_dict["query_time"],
hit_cache=render_dict["hit_cache"],
)

# Create bare-bones alert form.
alert_form = CreateAlertForm(
initial={"query": get_string, "rate": "dly"},
Expand Down
Loading