+def find_best_matches(query, user):
+ """ Finds a Book, Tag or Bookstub best matching a query.
+
+ Returns a with:
+ - zero elements when nothing is found,
+ - one element when a best result is found,
+ - more then one element on multiple exact matches
+
+ Raises a ValueError on too short a query.
+ """
+
+ query = query.lower()
+ if len(query) < 2:
+ raise ValueError("query must have at least two characters")
+
+ result = tuple(_tags_starting_with(query, user))
+ exact_matches = tuple(res for res in result if res.name.lower() == query)
+ if exact_matches:
+ return exact_matches
+ else:
+ return result[:1]
+
+