From 685c719ec1c2c5a2d418492baa9b369fbfb77a7a Mon Sep 17 00:00:00 2001 From: Jack Stdin Date: Sun, 21 Feb 2016 21:55:46 +0300 Subject: [PATCH] Add short name splitting into second field --- aore/fias/search.py | 36 +++++++++++++++++-------------- aore/fias/wordentry.py | 27 ++++++++++++++--------- aore/templates/sphinx/sphinx.conf | 2 +- aore/updater/xmlparser.py | 2 +- manage.py | 2 +- 5 files changed, 40 insertions(+), 29 deletions(-) diff --git a/aore/fias/search.py b/aore/fias/search.py index 1be8070..1add937 100644 --- a/aore/fias/search.py +++ b/aore/fias/search.py @@ -28,7 +28,7 @@ class SphinxSearch: sphinx_host = sphinx_conf.listen sphinx_port = None - if ":" in sphinx_conf.listen: + if ":" in sphinx_conf.listen and "unix:/" not in sphinx_conf.listen: sphinx_host, sphinx_port = sphinx_conf.listen.split(":") sphinx_port = int(sphinx_port) @@ -51,7 +51,7 @@ class SphinxSearch: self.client_sugg.SetSortMode(sphinxapi.SPH_SORT_EXTENDED, "krank DESC") else: self.client_show.SetRankingMode(sphinxapi.SPH_RANK_BM25) - self.client_show.SetSelect("aoid, fullname, @weight-abs(wordcount-{}) AS krank".format(word_len)) + self.client_show.SetSelect("aoid, fullname, @weight-2*abs(wordcount-{}) AS krank".format(word_len)) self.client_show.SetSortMode(sphinxapi.SPH_SORT_EXTENDED, "krank DESC") def __get_suggest(self, word, rating_limit, count): @@ -98,7 +98,7 @@ class SphinxSearch: def find(self, text, strong): def split_phrase(phrase): - phrase = unicode(phrase).replace('-', '').replace('@', '').lower() + phrase = unicode(phrase).lower() return re.split(r"[ ,:.#$]+", phrase) # сплитим текст на слова @@ -126,20 +126,24 @@ class SphinxSearch: # формируем строки для поиска в Сфинксе for i in range(good_vars_word_count, max(0, good_vars_word_count - 3), -1): first_q = "@fullname \"{}\"/{}".format(" ".join(good_var.text for good_var in good_vars), i) + if self.search_freq_words and freq_vars_word_count: + second_q = " @sname {}".format(" ".join(freq_var.text for freq_var in freq_vars)) + self.client_show.AddQuery(first_q + second_q, sphinx_conf.index_addjobj) + self.client_show.AddQuery(first_q, sphinx_conf.index_addjobj) - if self.search_freq_words: - for j in range(freq_vars_word_count, -1, -1): - if j == 0: - second_q = "" - else: - second_q = " @sname \"{}\"/{}".format(" ".join(freq_var.text for freq_var in freq_vars), j) - second_q = second_q.replace("*", "") - - print first_q + second_q - self.client_show.AddQuery(first_q + second_q, sphinx_conf.index_addjobj) - else: - print first_q - self.client_show.AddQuery(first_q, sphinx_conf.index_addjobj) + # if self.search_freq_words: + # for j in range(freq_vars_word_count, -1, -1): + # if j == 0: + # second_q = "" + # else: + # second_q = " @sname {}".format(" | ".join(freq_var.text for freq_var in freq_vars), j) + # second_q = second_q.replace("*", "") + # + # print first_q + second_q + # self.client_show.AddQuery(first_q + second_q, sphinx_conf.index_addjobj) + # else: + # print first_q + # self.client_show.AddQuery(first_q, sphinx_conf.index_addjobj) self.__configure(sphinx_conf.index_addjobj, word_count) diff --git a/aore/fias/wordentry.py b/aore/fias/wordentry.py index bea200d..53d067c 100644 --- a/aore/fias/wordentry.py +++ b/aore/fias/wordentry.py @@ -19,7 +19,7 @@ class WordEntry: # -1x - одно по лайку и много точных. Быть не может. # x0 - много по лайку и нет точных. Недопечатка. Немного подсказок и *. # x1 - много по лайку и один точный. Чет нашли. Как есть и *. - # xx - много по лайку и много точных. Оставляем как есть и * TODO В данном случае лайк лучше убрать + # xx - много по лайку и много точных. Оставляем как есть и * # # Теперь по сокращениям. Они работюат отдельно (ПОКА ЧТО) # 3rd - кол-во слов по точному совпдению по полному сокращению. @@ -37,9 +37,10 @@ class WordEntry: match_types = dict( MT_MANY_SUGG=['0000'], MT_SOME_SUGG=['10..', 'x0..'], - MT_LAST_STAR=['10..', 'x...'], + MT_LAST_STAR=['100.', 'x.0.'], MT_AS_IS=['.1..', '...1', '...x'], - MT_ADD_SOCR=['..10', '..x0'] + MT_ADD_SOCR=['..10', '..x0'], + MT_IS_SOCR=['..01', '..0x'] ) rating_limit_soft = 0.41 @@ -50,7 +51,8 @@ class WordEntry: def __init__(self, db, word): self.db = db - self.word = str(word) + self.bare_word = str(word) + self.word = self.__cleanify(self.bare_word) self.word_len = len(unicode(self.word)) self.parameters = dict(IS_FREQ=False, SOCR_WORD=None) self.ranks = self.__init_ranks() @@ -59,18 +61,20 @@ class WordEntry: for mt_name, mt_values in self.match_types.iteritems(): self.__dict__[mt_name] = False for mt_value in mt_values: - self.__dict__[mt_name] = self.__dict__[mt_name] or re.search(mt_value, self.ranks) is not None + self.__dict__[mt_name] = self.__dict__[mt_name] or re.search(mt_value, self.ranks) # Если ищем по лайку, то точное совпадение не ищем (оно и так будет включено) if self.MT_LAST_STAR: self.MT_AS_IS = False # Строка слишком котроткая, то по лайку не ищем, сфинкс такого не прожует - # Если найдено сокращение, то по лайку тоже не ищем TODO добавить это в правила - if self.MT_LAST_STAR and (self.word_len < sphinx_conf.min_length_to_star or self.MT_ADD_SOCR): + if self.MT_LAST_STAR and self.word_len < sphinx_conf.min_length_to_star: self.MT_LAST_STAR = False self.MT_AS_IS = True + def __cleanify(self, word): + return word.replace('-', '').replace('@', '') + def variations_gen(self, strong, suggestion_func): default_var_type = VariationType.normal # Если слово встречается часто, ставим у всех вариантов тип VariationType.freq @@ -93,9 +97,12 @@ class WordEntry: if self.MT_LAST_STAR: yield WordVariation(self, self.word + '*', default_var_type) - # Добавляем слово "как есть" + # Добавляем слово "как есть", если это сокращение, то добавляем как частое слово if self.MT_AS_IS: - yield WordVariation(self, self.word, default_var_type) + var_t = default_var_type + if self.MT_IS_SOCR: + var_t = VariationType.freq + yield WordVariation(self, self.word, var_t) # -- Дополнительные функции -- # Добавляем сокращение @@ -109,7 +116,7 @@ class WordEntry: "UNION ALL SELECT COUNT(*), MAX(scname) FROM \"SOCRBASE\" WHERE socrname ILIKE '{}'" \ "UNION ALL SELECT COUNT(*), NULL FROM \"SOCRBASE\" WHERE scname ILIKE '{}'" \ "UNION ALL SELECT frequency, NULL FROM \"AOTRIG\" WHERE word='{}';".format( - self.word, self.word_len, self.word, self.word, self.word, self.word) + self.word, self.word_len, self.word, self.bare_word, self.bare_word, self.word) result = self.db.get_rows(sql_qry) diff --git a/aore/templates/sphinx/sphinx.conf b/aore/templates/sphinx/sphinx.conf index 8794e3b..16c7758 100644 --- a/aore/templates/sphinx/sphinx.conf +++ b/aore/templates/sphinx/sphinx.conf @@ -60,6 +60,6 @@ searchd # optional, default is 1 (do unlink) unlink_old = 1 - expansion_limit = 48 + expansion_limit = 32 } diff --git a/aore/updater/xmlparser.py b/aore/updater/xmlparser.py index e33bb2f..a6bddb3 100644 --- a/aore/updater/xmlparser.py +++ b/aore/updater/xmlparser.py @@ -15,7 +15,7 @@ class XMLParser: elem.clear() # Also eliminate now-empty references from the root node to elem for ancestor in elem.xpath('ancestor-or-self::*'): - while ancestor.getprevious() is not None: + while ancestor.getprevious(): del ancestor.getparent()[0] del context diff --git a/manage.py b/manage.py index 423f515..9a2c1f3 100644 --- a/manage.py +++ b/manage.py @@ -20,7 +20,7 @@ def print_fias_versions(): print("Number\t\tDate") for upd in all_versions: mark_current = (' ', '*')[int(upd['intver']) == current_version] - print "{}{}\t\t{}".format(mark_current, upd['intver'], upd['strver']) + print("{}{}\t\t{}".format(mark_current, upd['intver'], upd['strver'])) def parse_update_str(updates_str):