Простое решение - это добавить поля (возможно скрытые от пользователей) для хранения тегов к курсам и статьям, а потом делать выборку по совпадающим тегам и сортировать результат по количеству совпадений.
Вариант посложнее - при показе курса, полнотекстовым поиском искать его заголовок среди статей и наоборот.
Совсем свирепый вариант - с помощью чего-нибудь типа
NLTK анализировать тексты всех сущностей и автоматически выстраивать между ними связи M2M.