Skip to content

Commit

Permalink
feat: remove soft-deleted collections from the Studio search index
Browse files Browse the repository at this point in the history
  • Loading branch information
pomegranited committed Sep 18, 2024
1 parent 9cdb054 commit dd78988
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 2 deletions.
32 changes: 30 additions & 2 deletions openedx/core/djangoapps/content/search/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,28 @@ def _update_index_docs(docs) -> None:
_wait_for_meili_tasks(tasks)


def _delete_index_docs(docs) -> None:
"""
Helper function that deletes the given documents from the search index
If there is a rebuild in progress, the document will also be removed from the new index.
"""
if not docs:
return

client = _get_meilisearch_client()
current_rebuild_index_name = _get_running_rebuild_index_name()

tasks = []
if current_rebuild_index_name:
# If there is a rebuild in progress, the document will also be removed from the new index.
tasks.append(client.index(current_rebuild_index_name).delete_documents(docs))

tasks.append(client.index(STUDIO_INDEX_NAME).delete_documents(docs))

_wait_for_meili_tasks(tasks)


def only_if_meilisearch_enabled(f):
"""
Only call `f` if meilisearch is enabled
Expand Down Expand Up @@ -563,18 +585,24 @@ def upsert_library_block_index_doc(usage_key: UsageKey) -> None:

def upsert_library_collection_index_doc(library_key: LibraryLocatorV2, collection_key: str) -> None:
"""
Creates or updates the document for the given Library Collection in the search index
Creates, updates, or deletes the document for the given Library Collection in the search index.
If the Collection is disabled (i.e. soft-deleted), then delete it from the search index.
"""
content_library = lib_api.ContentLibrary.objects.get_by_key(library_key)
collection = authoring_api.get_collection(
learning_package_id=content_library.learning_package_id,
collection_key=collection_key,
)

docs = [
searchable_doc_for_collection(collection)
]
if collection.id and collection.enabled:
_update_index_docs(docs)

_update_index_docs(docs)
else:
_delete_index_docs(docs)


def upsert_content_library_index_docs(library_key: LibraryLocatorV2) -> None:
Expand Down
69 changes: 69 additions & 0 deletions openedx/core/djangoapps/content/search/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -615,3 +615,72 @@ def test_index_tags_in_collections(self, mock_meilisearch):
],
any_order=True,
)

@override_settings(MEILISEARCH_ENABLED=True)
def test_delete_collection(self, mock_meilisearch):
# Add a component to the collection
updated_date = datetime(2023, 6, 7, 8, 9, 10, tzinfo=timezone.utc)
with freeze_time(updated_date):
library_api.update_library_collection_components(
self.library.key,
collection_key=self.collection.key,
usage_keys=[
self.problem1.usage_key,
],
)

doc_collection = copy.deepcopy(self.collection_dict)
doc_collection["num_children"] = 1
doc_collection["modified"] = updated_date.timestamp()
doc_problem_with_collection = {
"id": self.doc_problem1["id"],
"collections": {
"display_name": [self.collection.title],
"key": [self.collection.key],
},
}
assert mock_meilisearch.return_value.index.return_value.update_documents.call_count == 2
mock_meilisearch.return_value.index.return_value.update_documents.assert_has_calls(
[
call([doc_collection]),
call([doc_problem_with_collection]),
],
any_order=True,
)
mock_meilisearch.return_value.index.reset_mock()

# Soft-delete the collection
deleted_date = datetime(2023, 7, 8, 9, 10, 11, tzinfo=timezone.utc)
with freeze_time(deleted_date):
authoring_api.delete_collection(
self.collection.learning_package_id,
self.collection.key,
)

doc_collection["modified"] = deleted_date.timestamp()
doc_problem_without_collection = {
"id": self.doc_problem1["id"],
"collections": {},
}

mock_meilisearch.return_value.index.return_value.delete_documents.assert_called_once_with([doc_collection])
## TODO: how/where to update the components in a soft-deleted collection?
# mock_meilisearch.return_value.index.return_value.update_documents.assert_called_once_with([
# doc_problem_without_collection
# ])

# Restore the collection
restored_date = datetime(2023, 8, 9, 10, 11, 12, tzinfo=timezone.utc)
with freeze_time(restored_date):
authoring_api.restore_collection(
self.collection.learning_package_id,
self.collection.key,
)

doc_collection["modified"] = restored_date.timestamp()

mock_meilisearch.return_value.index.return_value.update_documents.assert_called_once_with([doc_collection])
## TODO: how/where to update the components in a restored collection?
# mock_meilisearch.return_value.index.return_value.update_documents.assert_called_once_with([
# doc_problem_with_collection
# ])

0 comments on commit dd78988

Please sign in to comment.