Add short name splitting into second field

This commit is contained in:
Jack Stdin 2016-02-21 21:55:46 +03:00
parent c4b516a28c
commit 685c719ec1
5 changed files with 40 additions and 29 deletions

View File

@ -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)

View File

@ -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)

View File

@ -60,6 +60,6 @@ searchd
# optional, default is 1 (do unlink)
unlink_old = 1
expansion_limit = 48
expansion_limit = 32
}

View File

@ -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

View File

@ -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):