diff --git a/enterprise_catalog/apps/api_client/algolia.py b/enterprise_catalog/apps/api_client/algolia.py index 6387223b..c50361b4 100644 --- a/enterprise_catalog/apps/api_client/algolia.py +++ b/enterprise_catalog/apps/api_client/algolia.py @@ -20,16 +20,18 @@ class AlgoliaSearchClient: ALGOLIA_APPLICATION_ID = settings.ALGOLIA.get('APPLICATION_ID') ALGOLIA_API_KEY = settings.ALGOLIA.get('API_KEY') ALGOLIA_INDEX_NAME = settings.ALGOLIA.get('INDEX_NAME') + ALGOLIA_REPLICA_INDEX_NAME = settings.ALGOLIA.get('REPLICA_INDEX_NAME') def __init__(self): self._client = None self.algolia_index = None + self.replica_index = None def init_index(self): """ Initializes an index within Algolia. Initializing an index will create it if it doesn't exist. """ - if not self.ALGOLIA_INDEX_NAME: + if not self.ALGOLIA_INDEX_NAME or not self.ALGOLIA_REPLICA_INDEX_NAME: logger.error('Could not initialize Algolia index due to missing index name.') return @@ -44,6 +46,7 @@ def init_index(self): self._client = SearchClient.create(self.ALGOLIA_APPLICATION_ID, self.ALGOLIA_API_KEY) try: self.algolia_index = self._client.init_index(self.ALGOLIA_INDEX_NAME) + self.replica_index = self._client.init_index(self.ALGOLIA_REPLICA_INDEX_NAME) except AlgoliaException as exc: logger.exception( 'Could not initialize %s index in Algolia due to an exception.', @@ -51,7 +54,7 @@ def init_index(self): ) raise exc - def set_index_settings(self, index_settings): + def set_index_settings(self, index_settings, primary_index=True): """ Set default settings to use for the Algolia index. @@ -66,7 +69,10 @@ def set_index_settings(self, index_settings): return try: - self.algolia_index.set_settings(index_settings) + if primary_index: + self.algolia_index.set_settings(index_settings) + else: + self.replica_index.set_settings(index_settings) except AlgoliaException as exc: logger.exception( 'Unable to set settings for Algolia\'s %s index due to an exception.', @@ -78,18 +84,24 @@ def index_exists(self): """ Returns whether the index exists in Algolia. """ - if not self.algolia_index: + if not self.algolia_index or not self.replica_index: logger.error('Algolia index does not exist. Did you initialize it?') return False - exists = self.algolia_index.exists() - if not exists: + primary_exists = self.algolia_index.exists() + replica_exists = self.replica_index.exists() + if not primary_exists: logger.warning( 'Index with name %s does not exist in Algolia.', self.ALGOLIA_INDEX_NAME, ) + if not replica_exists: + logger.warning( + 'Index with name %s does not exist in Algolia.', + self.ALGOLIA_REPLICA_INDEX_NAME, + ) - return exists + return primary_exists and replica_exists def replace_all_objects(self, algolia_objects): # pragma: no cover """ diff --git a/enterprise_catalog/apps/catalog/algolia_utils.py b/enterprise_catalog/apps/catalog/algolia_utils.py index 855a93b6..3a75247d 100644 --- a/enterprise_catalog/apps/catalog/algolia_utils.py +++ b/enterprise_catalog/apps/catalog/algolia_utils.py @@ -4,6 +4,7 @@ import time from dateutil import parser +from django.conf import settings from django.core.cache import cache from django.db.models import Q from django.utils.dateparse import parse_datetime @@ -53,7 +54,9 @@ ALGOLIA_UUID_BATCH_SIZE = 100 ALGOLIA_JSON_METADATA_MAX_SIZE = 100000 +ALGOLIA_REPLICA_INDEX_NAME = settings.ALGOLIA.get('REPLICA_INDEX_NAME') +algolia_replica_index = f'virtual({ALGOLIA_REPLICA_INDEX_NAME})' # keep attributes from content objects that we explicitly want in Algolia ALGOLIA_FIELDS = [ @@ -183,6 +186,15 @@ 'desc(course_bayesian_average)', 'desc(recent_enrollment_count)', ], + 'replicas': [ + algolia_replica_index + ], +} + +ALGOLIA_REPLICA_INDEX_SETTINGS = { + 'customRanking': [ + 'desc(duration)' + ], } @@ -354,6 +366,7 @@ def configure_algolia_index(algolia_client): Configures the settings for an Algolia index. """ algolia_client.set_index_settings(ALGOLIA_INDEX_SETTINGS) + algolia_client.set_index_settings(ALGOLIA_REPLICA_INDEX_SETTINGS, primary_index=False) def get_algolia_object_id(content_type, uuid): diff --git a/enterprise_catalog/apps/catalog/tests/test_algolia_utils.py b/enterprise_catalog/apps/catalog/tests/test_algolia_utils.py index 81ab4523..d4513d95 100644 --- a/enterprise_catalog/apps/catalog/tests/test_algolia_utils.py +++ b/enterprise_catalog/apps/catalog/tests/test_algolia_utils.py @@ -1058,7 +1058,11 @@ def test_configure_algolia_index(self, mock_search_client): """ algolia_client = utils.get_initialized_algolia_client() utils.configure_algolia_index(algolia_client) - mock_search_client.return_value.set_index_settings.assert_called_once_with(utils.ALGOLIA_INDEX_SETTINGS) + mock_search_client.return_value.set_index_settings.assert_any_call(utils.ALGOLIA_INDEX_SETTINGS) + mock_search_client.return_value.set_index_settings.assert_called_with( + utils.ALGOLIA_REPLICA_INDEX_SETTINGS, + primary_index=False + ) @ddt.data( (