-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Search analytics #6019
Search analytics #6019
Changes from 11 commits
7477591
68c7f23
c161dcd
c463226
8d65c70
43aa613
483d07b
d1e3f3c
6406871
55611bf
5d2a947
af37565
9cdef59
dc12a22
5ad4752
cc8ac82
f4e68ee
9ab6af5
4e17e7b
a26cd44
a20a01b
f25c8e6
ef8acfd
8b9eafd
52bce57
7a8edc1
c7c9336
3097be0
9e3df32
306c47c
75bfd13
199867c
3880f4b
53777ba
94310f9
6b8ad1f
fbc14d5
8670741
53c9a67
b8e786b
a358bf0
343bdc2
0d83ba6
3cce53f
4c720ca
3f06d8d
372f1ac
324ff36
13a6205
13b6880
c8fea2c
862ab30
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
"""SearchQuery Admin classes.""" | ||
|
||
from django.contrib import admin | ||
|
||
from .models import SearchQuery | ||
|
||
|
||
class SearchQueryAdmin(admin.ModelAdmin): | ||
list_filter = ('created',) | ||
list_display = ('__str__', 'count', 'created', 'modified') | ||
search_fields = ('project__slug', 'version__slug', 'query') | ||
readonly_fields = ('created', 'modified') | ||
list_select_related = ('project', 'version', 'version__project') | ||
|
||
|
||
admin.site.register(SearchQuery, SearchQueryAdmin) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# -*- coding: utf-8 -*- | ||
# Generated by Django 1.11.22 on 2019-07-31 14:25 | ||
from __future__ import unicode_literals | ||
|
||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
import django_extensions.db.fields | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
('projects', '0044_auto_20190703_1300'), | ||
('builds', '0009_added_external_version_type'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='SearchQuery', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')), | ||
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')), | ||
('query', models.CharField(max_length=4092, verbose_name='Query')), | ||
('count', models.PositiveIntegerField(default=1, verbose_name='No. of times this query was searched')), | ||
('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='search_queries', to='projects.Project')), | ||
('version', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='search_queries', to='builds.Version', verbose_name='Version')), | ||
], | ||
options={ | ||
'verbose_name': 'Search query', | ||
'verbose_name_plural': 'Search queries', | ||
}, | ||
), | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
"""Search Queries.""" | ||
|
||
from django.db import models | ||
from django.utils.translation import ugettext_lazy as _ | ||
|
||
from django_extensions.db.models import TimeStampedModel | ||
|
||
from readthedocs.builds.models import Version | ||
from readthedocs.projects.models import Project | ||
from readthedocs.projects.querysets import RelatedProjectQuerySet | ||
|
||
|
||
class SearchQuery(TimeStampedModel): | ||
|
||
"""Information about the search queries.""" | ||
|
||
project = models.ForeignKey( | ||
Project, | ||
related_name='search_queries', | ||
on_delete=models.CASCADE, | ||
) | ||
version = models.ForeignKey( | ||
Version, | ||
verbose_name=_('Version'), | ||
related_name='search_queries', | ||
on_delete=models.CASCADE, | ||
) | ||
query = models.CharField( | ||
_('Query'), | ||
max_length=4092, | ||
) | ||
count = models.PositiveIntegerField( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering if we want more data here. Should we be storing an object each time a search happens? That way we can show the frequency of a search over time. Currently, this only tells us how many times a search has happened. I think if we plan to delete the data every 3 months, we can probably store every search query with it's own timestamp. I'm fine with shipping this initially though, before we start storing a lot more data. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure what you meant be Storing search object everytime a search was made is a better idea. I realised that the graphs were wrong before. And going this way makes them correct and easier.
Can you exapand this more?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just that we will be able to see when a specific search was done each time it was done. The current modeling only shows the number of times a search was done, but no time data about each search. |
||
_('No. of times this query was searched'), | ||
default=1, | ||
) | ||
objects = RelatedProjectQuerySet.as_manager() | ||
|
||
class Meta: | ||
verbose_name = 'Search query' | ||
verbose_name_plural = 'Search queries' | ||
|
||
def __str__(self): | ||
return f'[{self.project.slug}:{self.version.slug}]: {self.query}' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if we really even want to cascade these deletes. Is there a reason we don't want to store Version here as a string, so we can keep them forever even if a version is deleted?