def test_delete(self): """ Items should be removed from the index when they are deleted. """ orig_count = search_index().count() self.resource.delete() self.assertEqual(search_index().count(), orig_count - 1)
def construct_queryset(repo_slug, query='', selected_facets=None, sortby=''): """ Create a SearchQuerySet given search parameters. Args: repo_slug (learningresources.models.Repository): Slug for repository being searched. query (unicode): If present, search phrase to use in queryset. selected_facets (list or None): If present, a list of facets to narrow the search with. sortby (unicode): If present, order by this sorting option. Returns: search.utils/SearchResults: The search results. """ if selected_facets is None: selected_facets = [] kwargs = {} if query != "": kwargs["content"] = query if sortby == "": sortby = LoreSortingFields.DEFAULT_SORTING_FIELD # default values in case of weird sorting options sortby, _, order_direction = LoreSortingFields.get_sorting_option( sortby) sortby = "{0}{1}".format(order_direction, sortby) # Do a parallel query using elasticsearch-dsl. if query not in ("", None): tokens = query else: tokens = None terms = {} for facet in selected_facets: key, value = facet.split(":") # Haystack queries for blanks by putting the key last, as the value, # and setting the key to "_missing_." Fix this for elasticsearch-dsl. if key == '_missing_': key, value = value, None if key.endswith("_exact"): key = key[:-len("_exact")] terms[key] = value # This is sneakily being returned instead of the # Haystack queryset created above. results = search_index( tokens=tokens, repo_slug=repo_slug, sort_by=sortby, terms=terms, ) return results
def test_update(self): """ Items should only be indexed on update, not creation. During course import, a bulk indexing will occur. """ orig_count = search_index().count() new_resource = LearningResource.objects.create( course=self.resource.course, learning_resource_type=self.resource.learning_resource_type, title="accordion music", content_xml="<blah>foo</blah>", materialized_path="/foo", url_name="url_name2", ) self.assertEqual(search_index().count(), orig_count) # no indexing new_resource.save() # triggers post_save signal with created=False self.assertEqual(search_index().count(), orig_count + 1)
def construct_queryset(repo_slug, query='', selected_facets=None, sortby=''): """ Create a SearchQuerySet given search parameters. Args: repo_slug (learningresources.models.Repository): Slug for repository being searched. query (unicode): If present, search phrase to use in queryset. selected_facets (list or None): If present, a list of facets to narrow the search with. sortby (unicode): If present, order by this sorting option. Returns: search.utils/SearchResults: The search results. """ if selected_facets is None: selected_facets = [] kwargs = {} if query != "": kwargs["content"] = query if sortby == "": sortby = LoreSortingFields.DEFAULT_SORTING_FIELD # default values in case of weird sorting options sortby, _, order_direction = LoreSortingFields.get_sorting_option(sortby) sortby = "{0}{1}".format(order_direction, sortby) # Do a parallel query using elasticsearch-dsl. if query not in ("", None): tokens = query else: tokens = None terms = {} for facet in selected_facets: key, value = facet.split(":") # Haystack queries for blanks by putting the key last, as the value, # and setting the key to "_missing_." Fix this for elasticsearch-dsl. if key == '_missing_': key, value = value, None if key.endswith("_exact"): key = key[:-len("_exact")] terms[key] = value # This is sneakily being returned instead of the # Haystack queryset created above. results = search_index( tokens=tokens, repo_slug=repo_slug, sort_by=sortby, terms=terms, ) return results
def test_search_fields(self): """ The content_xml, title, and description should be searchable by partial matches. """ new_resource = LearningResource.objects.create( course=self.resource.course, learning_resource_type=self.resource.learning_resource_type, title="accordion music", content_xml="<blah>foo</blah>", materialized_path="/foo", url_name="url_name2", description="the quick brown fox", description_path="silver", ) new_resource.save() # to trigger indexing refresh_index() self.assertEqual(search_index("accordion").count(), 1) self.assertEqual(search_index("fox brown").count(), 1) self.assertEqual(search_index("foo").count(), 1)
def test_import(self): """ Indexing should occur on course import. """ results = search_index() original_count = results.count() import_course_from_file(self.course_zip, self.repo.id, self.user.id) refresh_index() results = search_index() self.assertEqual(results.count(), original_count + 18) self.assertEqual(results.page_count(), 2) # Ensure the correct number of results are returned in each page. self.assertEqual(len(results.get_page(1)), 10) self.assertEqual(len(results.get_page(2)), 9) self.assertEqual(len(results.get_page(3)), 0) # Make sure the .all() function (a convenience function which # returns a generator), returns all the records without explicit # pagination. count = 0 for _ in results.all(): count += 1 self.assertEqual(count, results.count())
def count_faceted_results(self, vocab_id, term_id): """Return count of matching indexed records by facet.""" return search_index( repo_slug=self.repo.slug, terms={make_vocab_key(vocab_id): term_id} ).count()
def search(self, query, sorting=LoreSortingFields.DEFAULT_SORTING_FIELD): """ Helper function to perform a search """ return search_index(query, repo_slug=self.repo.slug, sort_by=sorting)