Вместо полнотекстового поиска в GAE я использую приведенное ниже решение, чтобы вернуть отсортированный набор результатов, сначала по релевантности по ключевым словам, а затем по дате (хотя на самом деле вторая сортировка может быть чем угодно).Это кажется немного громоздким, и я беспокоюсь о производительности в масштабе, поэтому я ищу предложения по оптимизации или совсем другой подход.
Вторичная сортировка важна для моего варианта использования, так как данный поиск, скорее всего, будетиметь несколько результатов одинаковой релевантности (измеряемой количеством совпадений ключевых слов), но сохранение исходного порядка запросов в настоящее время значительно усложняет задачу.Есть идеи?
Шаг 1: Получить список ключей, соответствующих каждому поисковому запросу
results_key_list = []
search_terms = ['a','b','c'] #User's search query, split into a list of strings
#query each search term and add the results to a list
#yields a list of keys with frequency of occurance indicating relevance
for item in search_terms:
subquery = SomeEntity.all(keys_only=True)
subquery.filter('SearchIndex = ', item) #SearchIndex is a StringListProperty
#more filters...
subquery.order('-DateCreated')
for returned_item in subquery:
results_key_list.append(str(returned_item))
Шаг 2: Сгруппировать список по частоте, сохраняя при этом первоначальный порядок
#return a dictionary of keys, with their frequency of occurrence
grouped_results = defaultdict(int)
for key in results_key_list:
grouped_results[key] += 1
sorted_results = []
known = set()
#creates an empty list for each match frequency
for i in range(len(search_terms)):
sorted_results.append([])
#using the original results ordering,
#construct an array of results grouped and ordered by descending frequency
for key in results_key_list:
if key in known: continue
frequency = grouped_results[key]
sorted_results[len(search_terms) - frequency].append(key)
known.add(key)
#combine into a single list
ordered_key_list = []
for l in sorted_results:
ordered_key_list.extend(l)
del ordered_key_list[:offset]
del ordered_key_list[limit:]
result = SomeEntity.get(ordered_key_list)