-
-
Notifications
You must be signed in to change notification settings - Fork 302
Import from other channels search optimized #3399
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
Changes from all commits
357204c
9028b22
d24416c
676526e
6d40c55
094f05f
701ddc9
1a14749
bff595c
8b7152e
c0e55ee
34e8436
e00c512
f3280d9
475aeef
3ff0edd
fffd912
974b69e
e15b015
aa62dc2
2672512
1ffa30d
55e4acf
57724e0
e53e56a
4b3d4c7
44ab74c
4beaf3c
001e788
ff59495
9ec60cf
aae3be1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,8 +18,11 @@ | |
| from django.core.files.storage import default_storage as storage | ||
| from django.core.management import call_command | ||
| from django.db.models import Count | ||
| from django.db.models import Exists | ||
| from django.db.models import Max | ||
| from django.db.models import OuterRef | ||
| from django.db.models import Q | ||
| from django.db.models import Subquery | ||
| from django.db.models import Sum | ||
| from django.db.utils import IntegrityError | ||
| from django.template.loader import render_to_string | ||
|
|
@@ -37,6 +40,10 @@ | |
| from le_utils.constants import roles | ||
| from past.builtins import basestring | ||
| from past.utils import old_div | ||
| from search.models import ChannelFullTextSearch | ||
| from search.models import ContentNodeFullTextSearch | ||
| from search.utils import get_fts_annotated_channel_qs | ||
| from search.utils import get_fts_annotated_contentnode_qs | ||
|
|
||
| from contentcuration import models as ccmodels | ||
| from contentcuration.decorators import delay_user_storage_calculation | ||
|
|
@@ -808,6 +815,50 @@ def fill_published_fields(channel, version_notes): | |
| channel.save() | ||
|
|
||
|
|
||
| def sync_contentnode_and_channel_tsvectors(channel_id): | ||
| """ | ||
| Creates, deletes and updates tsvectors of the channel and all its content nodes | ||
| to reflect the current state of channel's main tree. | ||
| """ | ||
| # Update or create channel tsvector entry. | ||
| logging.info("Setting tsvector for channel with id {}.".format(channel_id)) | ||
|
|
||
| channel = (get_fts_annotated_channel_qs() | ||
| .values("keywords_tsvector", "main_tree__tree_id") | ||
| .get(pk=channel_id)) | ||
|
|
||
| obj, is_created = ChannelFullTextSearch.objects.update_or_create(channel_id=channel_id, defaults={"keywords_tsvector": channel["keywords_tsvector"]}) | ||
| del obj | ||
|
|
||
| if is_created: | ||
| logging.info("Created 1 channel tsvector.") | ||
| else: | ||
| logging.info("Updated 1 channel tsvector.") | ||
|
|
||
| # Update or create contentnodes tsvector entry for channel_id. | ||
| logging.info("Setting tsvectors for all main tree contentnodes in channel {}.".format(channel_id)) | ||
|
|
||
vkWeb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if ContentNodeFullTextSearch.objects.filter(channel_id=channel_id).exists(): | ||
| # First, delete nodes that are no longer in main_tree. | ||
| nodes_no_longer_in_main_tree = ~Exists(ccmodels.ContentNode.objects.filter(id=OuterRef("contentnode_id"), tree_id=channel["main_tree__tree_id"])) | ||
| ContentNodeFullTextSearch.objects.filter(nodes_no_longer_in_main_tree, channel_id=channel_id).delete() | ||
|
|
||
vkWeb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| # Now, all remaining nodes are in main_tree, so let's update them. | ||
| # Update only changed nodes. | ||
| node_tsv_subquery = get_fts_annotated_contentnode_qs(channel_id).filter(id=OuterRef("contentnode_id")).order_by() | ||
| ContentNodeFullTextSearch.objects.filter(channel_id=channel_id, contentnode__complete=True, contentnode__changed=True).update( | ||
vkWeb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| keywords_tsvector=Subquery(node_tsv_subquery.values("keywords_tsvector")[:1]), | ||
| author_tsvector=Subquery(node_tsv_subquery.values("author_tsvector")[:1]) | ||
| ) | ||
|
|
||
| # Insert newly created nodes. | ||
| # "set_contentnode_tsvectors" command is defined in "search/management/commands" directory. | ||
| call_command("set_contentnode_tsvectors", | ||
| "--channel-id={}".format(channel_id), | ||
| "--tree-id={}".format(channel["main_tree__tree_id"]), | ||
| "--complete") | ||
|
Member
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. Any reason not to pass the command options as keyword args? It would be slightly cleaner. The only caveat is that it bypasses the argument parser, but for your purposes, I don't see that there would be a difference. https://docs.djangoproject.com/en/3.2/ref/django-admin/#django.core.management.call_command
Member
Author
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. The reason I chose this was to let the argument parser get invoked. It helped me manual test (and gave me the confidence) on what would happen when this command gets run from the commandline. |
||
|
|
||
|
|
||
| @delay_user_storage_calculation | ||
| def publish_channel( | ||
| user_id, | ||
|
|
@@ -829,8 +880,9 @@ def publish_channel( | |
| set_channel_icon_encoding(channel) | ||
| kolibri_temp_db = create_content_database(channel, force, user_id, force_exercises, progress_tracker=progress_tracker) | ||
| increment_channel_version(channel) | ||
| mark_all_nodes_as_published(channel) | ||
| add_tokens_to_channel(channel) | ||
| sync_contentnode_and_channel_tsvectors(channel_id=channel.id) | ||
| mark_all_nodes_as_published(channel) | ||
| fill_published_fields(channel, version_notes) | ||
|
|
||
| # Attributes not getting set for some reason, so just save it here | ||
|
|
||
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.