+
+
+def search_books(query):
+ search = Search()
+ results_parts = []
+ search_fields = []
+ words = query.split()
+ fieldsets = (
+ (['authors', 'authors_nonstem'], True),
+ (['title', 'title_nonstem'], True),
+ (['metadata', 'metadata_nonstem'], True),
+ (['text', 'text_nonstem', 'themes_pl', 'themes_pl_nonstem'], False),
+ )
+ for fields, is_book in fieldsets:
+ search_fields += fields
+ results_parts.append(search.search_words(words, search_fields, required=fields, book=is_book))
+ results = []
+ ids_results = {}
+ for results_part in results_parts:
+ for result in sorted(SearchResult.aggregate(results_part), reverse=True):
+ book_id = result.book_id
+ if book_id in ids_results:
+ ids_results[book_id].merge(result)
+ else:
+ results.append(result)
+ ids_results[book_id] = result
+ descendant_ids = set(
+ Book.objects.filter(id__in=ids_results, ancestor__in=ids_results).values_list('id', flat=True))
+ results = [result for result in results if result.book_id not in descendant_ids]
+ for result in results:
+ search.get_snippets(result, query, num=3)
+
+ def ensure_exists(r):
+ try:
+ return r.book
+ except Book.DoesNotExist:
+ return False
+
+ results = filter(ensure_exists, results)
+ return results
+
+
+def search_pictures(query):
+ search = Search()
+ results_parts = []
+ search_fields = []
+ words = query.split()
+ fieldsets = (
+ (['authors', 'authors_nonstem'], True),
+ (['title', 'title_nonstem'], True),
+ (['metadata', 'metadata_nonstem'], True),
+ (['themes_pl', 'themes_pl_nonstem'], False),
+ )
+ for fields, is_book in fieldsets:
+ search_fields += fields
+ results_parts.append(search.search_words(words, search_fields, required=fields, book=is_book, picture=True))
+ results = []
+ ids_results = {}
+ for results_part in results_parts:
+ for result in sorted(PictureResult.aggregate(results_part), reverse=True):
+ picture_id = result.picture_id
+ if picture_id in ids_results:
+ ids_results[picture_id].merge(result)
+ else:
+ results.append(result)
+ ids_results[picture_id] = result
+
+ def ensure_exists(r):
+ try:
+ return r.picture
+ except Picture.DoesNotExist:
+ return False
+
+ results = filter(ensure_exists, results)
+ return results
+
+
+def search_pd_authors(query):
+ pd_authors = Author.objects.filter(name__icontains=query)
+ existing_slugs = Tag.objects.filter(
+ category='author', slug__in=list(pd_authors.values_list('slug', flat=True))) \
+ .values_list('slug', flat=True)
+ pd_authors = pd_authors.exclude(slug__in=existing_slugs)
+ return pd_authors
+
+
+def prepare_query(query):
+ query = ' '.join(query.split())
+ # filter out private use characters
+ import unicodedata
+ query = ''.join(ch for ch in query if unicodedata.category(ch) != 'Co')
+ query = remove_query_syntax_chars(query)
+
+ words = query.split()
+ if len(words) > 10:
+ query = ' '.join(words[:10])
+ return query