def import_course(bundle, repo_id, user_id, static_dir): """ Import a course from an XBundle object. Args: bundle (xbundle.XBundle): Course as xbundle XML repo_id (int): Primary key of repository course belongs to user_id (int): Primary key of Django user doing the import static_dir (unicode): location of static files Returns: learningresources.models.Course """ src = bundle.course course = create_course( org=src.attrib["org"], repo_id=repo_id, course_number=src.attrib["course"], run=src.attrib["semester"], user_id=user_id, ) import_static_assets(course, static_dir) import_children(course, src, None, '') populate_xanalytics_fields.delay(course.id) # This triggers a bulk indexing of all LearningResource instances # for the course at once. index_resources( get_resources(repo_id).filter(course__id=course.id)) return course
def test_index_exception(self): """ Ensure that an exception is thrown if we have not indexed properly. """ # Delete the index remove_index() search_url = "/api/v1/repositories/{repo}/search/".format( repo=self.repo.slug) with self.assertRaises(ReindexException): self.client.get(search_url) # Create a mapping with self.assertRaises(ReindexException): # Mapping doesn't exist yet get_conn() conn = get_conn(verify=False) conn.indices.create(INDEX_NAME) conn.indices.refresh() create_mapping() resp = self.client.get(search_url) self.assertEqual(resp.status_code, HTTP_200_OK) self.assertEqual(json.loads(resp.content.decode('utf-8'))['count'], 0) # Reindex all resources resource_ids = LearningResource.objects.values_list("id", flat=True) index_resources(resource_ids) resp = self.client.get(search_url) self.assertEqual(resp.status_code, HTTP_200_OK) self.assertEqual( json.loads(resp.content.decode('utf-8'))['count'], len(resource_ids))
def import_course(bundle, repo_id, user_id, static_dir): """ Import a course from an XBundle object. Args: bundle (xbundle.XBundle): Course as xbundle XML repo_id (int): Primary key of repository course belongs to user_id (int): Primary key of Django user doing the import static_dir (unicode): location of static files Returns: learningresources.models.Course """ src = bundle.course course = create_course( org=src.attrib["org"], repo_id=repo_id, course_number=src.attrib["course"], run=src.attrib["semester"], user_id=user_id, ) import_static_assets(course, static_dir) import_children(course, src, None, '') populate_xanalytics_fields.delay(course.id) # This triggers a bulk indexing of all LearningResource instances # for the course at once. index_resources( get_resources(repo_id).filter(course__id=course.id).values_list( "id", flat=True)) return course
def handle_m2m_save(sender, **kwargs): """Update index when taxonomies are updated.""" from search.search_indexes import get_vocabs instance = kwargs.pop("instance") if instance.__class__.__name__ != "LearningResource": return # Update cache for the LearningResource if it's already set. get_vocabs(instance.id) # Update Elasticsearch index: from search.utils import index_resources index_resources([instance.id])
def handle_resource_update(sender, **kwargs): """Update index when a LearningResource is updated.""" if kwargs["created"]: # Don't index upon create because we handle this in bulk # in the importer, the only place we allow creation to happen. return instance = kwargs.pop("instance") if instance.__class__.__name__ != "LearningResource": return from search.utils import index_resources index_resources([instance.id])
def test_index_exception(self): """ Ensure that an exception is thrown if we have not indexed properly. """ # Delete the index remove_index() search_url = "/api/v1/repositories/{repo}/search/".format( repo=self.repo.slug ) with self.assertRaises(ReindexException): self.client.get(search_url) # Create a mapping with self.assertRaises(ReindexException): # Mapping doesn't exist yet get_conn() conn = get_conn(verify=False) conn.indices.create(INDEX_NAME) conn.indices.refresh() create_mapping() resp = self.client.get(search_url) self.assertEqual(resp.status_code, HTTP_200_OK) self.assertEqual(json.loads(resp.content.decode('utf-8'))['count'], 0) # Reindex all resources resource_ids = LearningResource.objects.values_list("id", flat=True) index_resources(resource_ids) resp = self.client.get(search_url) self.assertEqual(resp.status_code, HTTP_200_OK) self.assertEqual( json.loads(resp.content.decode('utf-8'))['count'], len(resource_ids) )
def test_sorting(self): """Test sorting for search""" # remove the default resource to control the environment self.resource.delete() # create some resources res1 = self.create_resource(**dict(resource_type="example", title="silly example 1", content_xml="<blah>blah 1</blah>", mpath="/blah1", xa_nr_views=1001, xa_nr_attempts=99, xa_avg_grade=9.9)) res2 = self.create_resource(**dict(resource_type="example", title="silly example 2", content_xml="<blah>blah 2</blah>", mpath="/blah2", xa_nr_views=1003, xa_nr_attempts=98, xa_avg_grade=6.8)) res3 = self.create_resource(**dict(resource_type="example", title="silly example 3", content_xml="<blah>blah 3</blah>", mpath="/blah3", xa_nr_views=1002, xa_nr_attempts=101, xa_avg_grade=7.3)) res4 = self.create_resource(**dict(resource_type="example", title="silly example 4", content_xml="<blah>blah 4</blah>", mpath="/blah3", xa_nr_views=1003, xa_nr_attempts=101, xa_avg_grade=9.9)) index_resources([res1.id, res2.id, res3.id, res4.id]) refresh_index() self.assertEqual(self.count_results(), 4) # sorting by number of views results = self.search(query=None, sorting="-{0}".format( LoreSortingFields.SORT_BY_NR_VIEWS[0])) # expected position res2, res4 top_res = results[0] sec_res = results[1] self.assertEqual(top_res.id, res2.id) self.assertEqual(sec_res.id, res4.id) # sorting by number of attempts results = self.search(query=None, sorting="-{0}".format( LoreSortingFields.SORT_BY_NR_ATTEMPTS[0])) # expected position res3, res4 top_res = results[0] sec_res = results[1] self.assertEqual(top_res.id, res3.id) self.assertEqual(sec_res.id, res4.id) # sorting by average grade results = self.search(query=None, sorting="-{0}".format( LoreSortingFields.SORT_BY_AVG_GRADE[0])) # expected position res1, res4 top_res = results[0] sec_res = results[1] self.assertEqual(top_res.id, res1.id) self.assertEqual(sec_res.id, res4.id)
def test_sorting(self): """Test sorting for search""" # remove the default resource to control the environment self.resource.delete() # create some resources res1 = self.create_resource(**dict( resource_type="example", title="silly example 1", content_xml="<blah>blah 1</blah>", mpath="/blah1", xa_nr_views=1001, xa_nr_attempts=99, xa_avg_grade=9.9 )) res2 = self.create_resource(**dict( resource_type="example", title="silly example 2", content_xml="<blah>blah 2</blah>", mpath="/blah2", xa_nr_views=1003, xa_nr_attempts=98, xa_avg_grade=6.8 )) res3 = self.create_resource(**dict( resource_type="example", title="silly example 3", content_xml="<blah>blah 3</blah>", mpath="/blah3", xa_nr_views=1002, xa_nr_attempts=101, xa_avg_grade=7.3 )) res4 = self.create_resource(**dict( resource_type="example", title="silly example 4", content_xml="<blah>blah 4</blah>", mpath="/blah3", xa_nr_views=1003, xa_nr_attempts=101, xa_avg_grade=9.9 )) index_resources([res1.id, res2.id, res3.id, res4.id]) refresh_index() self.assertEqual(self.count_results(), 4) # sorting by number of views results = self.search( query=None, sorting="-{0}".format(LoreSortingFields.SORT_BY_NR_VIEWS[0]) ) # expected position res2, res4 top_res = results[0] sec_res = results[1] self.assertEqual( top_res.id, res2.id ) self.assertEqual( sec_res.id, res4.id ) # sorting by number of attempts results = self.search( query=None, sorting="-{0}".format(LoreSortingFields.SORT_BY_NR_ATTEMPTS[0]) ) # expected position res3, res4 top_res = results[0] sec_res = results[1] self.assertEqual( top_res.id, res3.id ) self.assertEqual( sec_res.id, res4.id ) # sorting by average grade results = self.search( query=None, sorting="-{0}".format(LoreSortingFields.SORT_BY_AVG_GRADE[0]) ) # expected position res1, res4 top_res = results[0] sec_res = results[1] self.assertEqual( top_res.id, res1.id ) self.assertEqual( sec_res.id, res4.id )
def handle(self, *args, **options): """Refreshes the Elasticsearch index.""" create_mapping() index_resources(LearningResource.objects.values_list("id", flat=True))