Улучшен поиск, правки кода.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import psycopg2
|
||||
from bottle import template
|
||||
|
||||
import sys
|
||||
from aore.dbutils.dbimpl import DBImpl
|
||||
from aore.fias.search import SphinxSearch
|
||||
from aore.config import db_conf
|
||||
@@ -49,7 +49,7 @@ class FiasFactory:
|
||||
|
||||
results = self.searcher.find(text, strong)
|
||||
except Exception, err:
|
||||
return dict(error=err.message)
|
||||
return dict(error=err.args[0])
|
||||
|
||||
return results
|
||||
|
||||
@@ -61,7 +61,7 @@ class FiasFactory:
|
||||
sql_query = self.normalize_templ.replace("//aoid", aoid_guid)
|
||||
rows = self.db.get_rows(sql_query, True)
|
||||
except Exception, err:
|
||||
return dict(error=err.message)
|
||||
return dict(error=err.args[0])
|
||||
|
||||
if len(rows) == 0:
|
||||
return []
|
||||
@@ -80,6 +80,6 @@ class FiasFactory:
|
||||
sql_query = self.expand_templ.replace("//aoid", normalized_id)
|
||||
rows = self.db.get_rows(sql_query, True)
|
||||
except Exception, err:
|
||||
return dict(error=err.message)
|
||||
return dict(error=err.args[0])
|
||||
|
||||
return rows
|
||||
|
||||
@@ -36,15 +36,12 @@ class SphinxSearch:
|
||||
self.client_show.SetConnectTimeout(3.0)
|
||||
|
||||
def __configure(self, index_name, wlen=None):
|
||||
if index_name == sphinx_conf.index_sugg:
|
||||
if wlen:
|
||||
self.client_sugg.SetMatchMode(sphinxapi.SPH_MATCH_EXTENDED2)
|
||||
self.client_sugg.SetRankingMode(sphinxapi.SPH_RANK_WORDCOUNT)
|
||||
self.client_sugg.SetFilterRange("len", int(wlen) - self.delta_len, int(wlen) + self.delta_len)
|
||||
self.client_sugg.SetSelect("word, len, @weight+{}-abs(len-{}) AS krank".format(self.delta_len, wlen))
|
||||
self.client_sugg.SetSortMode(sphinxapi.SPH_SORT_EXTENDED, "krank DESC")
|
||||
if index_name == sphinx_conf.index_sugg and wlen:
|
||||
self.client_sugg.SetRankingMode(sphinxapi.SPH_RANK_BM25)
|
||||
self.client_sugg.SetFilterRange("len", int(wlen) - self.delta_len, int(wlen) + self.delta_len)
|
||||
self.client_sugg.SetSelect("word, len, @weight+{}-abs(len-{}) AS krank".format(self.delta_len, wlen))
|
||||
self.client_sugg.SetSortMode(sphinxapi.SPH_SORT_EXTENDED, "krank DESC")
|
||||
else:
|
||||
self.client_show.SetMatchMode(sphinxapi.SPH_MATCH_EXTENDED2)
|
||||
self.client_show.SetRankingMode(sphinxapi.SPH_RANK_BM25)
|
||||
self.client_show.SetSortMode(sphinxapi.SPH_SORT_RELEVANCE)
|
||||
|
||||
@@ -108,11 +105,11 @@ class SphinxSearch:
|
||||
we = WordEntry(self.db, word)
|
||||
self.__add_word_variations(we, strong)
|
||||
|
||||
if we.get_variations() == "()":
|
||||
raise BaseException("Cannot process sentence.")
|
||||
assert we.get_variations() != "()", "Cannot process sentence."
|
||||
yield we
|
||||
|
||||
def find(self, text, strong):
|
||||
logging.info("FIND ")
|
||||
words = self.__split_phrase(text)
|
||||
word_entries = self.__get_word_entries(words, strong)
|
||||
sentence = "{}".format(" MAYBE ".join(x.get_variations() for x in word_entries))
|
||||
|
||||
@@ -16,7 +16,7 @@ class WordEntry:
|
||||
# -1x - одно по лайку и много точных. Быть не может.
|
||||
# x0 - много по лайку и нет точных. Недопечатка. Немного подсказок и *.
|
||||
# x1 - много по лайку и один точный. Чет нашли. Как есть и *.
|
||||
# xx - много по лайку и много точных. Оставляем как есть и *
|
||||
# xx - много по лайку и много точных. Оставляем как есть и * TODO В данном случае лайк лучше убрать
|
||||
#
|
||||
# Теперь по сокращениям. Они работюат отдельно (ПОКА ЧТО)
|
||||
# 3rd - кол-во слов по точному совпдению по полному сокращению.
|
||||
@@ -29,7 +29,7 @@ class WordEntry:
|
||||
# 11 - найдено одно полное и одно малое. Бывает (допустим, 'сад'). Добавляем как есть.
|
||||
# -1x - найдено одно полное и куча малых. Ну бред.
|
||||
# x0 - найдено куча полных и ни одного малого. Добавляем малое.
|
||||
# x1 - Куча полных и 1 малое. TODO Хз, бывает ли. Не обрабатываем.
|
||||
# x1 - Куча полных и 1 малое. Хз, бывает ли. Не обрабатываем.
|
||||
# xx - Куча полных и куча малых. Не обрабатываем.
|
||||
match_types = dict(
|
||||
MT_MANY_SUGG=['0000'],
|
||||
@@ -39,9 +39,12 @@ class WordEntry:
|
||||
MT_ADD_SOCR=['..10', '..x0']
|
||||
)
|
||||
|
||||
min_word_len_to_star = 4
|
||||
|
||||
def __init__(self, db, word):
|
||||
self.db = db
|
||||
self.word = str(word)
|
||||
self.word_len = len(unicode(self.word))
|
||||
self.variations = []
|
||||
self.scname = None
|
||||
self.ranks = self.__get_ranks()
|
||||
@@ -51,9 +54,15 @@ class WordEntry:
|
||||
for z in y:
|
||||
self.__dict__[x] = self.__dict__[x] or re.search(z, self.ranks) is not None
|
||||
|
||||
# Если ищем по лайку, то точное совпадение не ищем (оно и так будет включено)
|
||||
if self.MT_LAST_STAR:
|
||||
self.MT_AS_IS = False
|
||||
|
||||
# Строка слишком котроткая, то по лайку не ищем, будет очень долго
|
||||
if self.MT_LAST_STAR and self.word_len < self.min_word_len_to_star:
|
||||
self.MT_LAST_STAR = False
|
||||
self.MT_AS_IS = True
|
||||
|
||||
def add_variation_socr(self):
|
||||
if self.scname:
|
||||
self.add_variation(self.scname)
|
||||
@@ -65,28 +74,32 @@ class WordEntry:
|
||||
return "({})".format(" | ".join(self.variations))
|
||||
|
||||
def __get_ranks(self):
|
||||
word_len = len(unicode(self.word))
|
||||
sql_qry = "SELECT COUNT(*), NULL FROM \"AOTRIG\" WHERE word LIKE '{}%' AND LENGTH(word) > {} " \
|
||||
"UNION ALL SELECT COUNT(*), NULL FROM \"AOTRIG\" WHERE word='{}' " \
|
||||
"UNION ALL SELECT COUNT(*), MAX(scname) FROM \"SOCRBASE\" WHERE socrname ILIKE '{}'" \
|
||||
"UNION ALL SELECT COUNT(*), NULL FROM \"SOCRBASE\" WHERE scname ILIKE '{}'".format(
|
||||
self.word, word_len, self.word, self.word, self.word)
|
||||
"UNION ALL SELECT COUNT(*), NULL FROM \"SOCRBASE\" WHERE scname ILIKE '{}';".format(
|
||||
self.word, self.word_len, self.word, self.word, self.word)
|
||||
|
||||
result = self.db.get_rows(sql_qry)
|
||||
|
||||
# Проставляем "сокращенное" сокращение, если нашли полное
|
||||
if not self.scname:
|
||||
self.scname = result[2][1]
|
||||
|
||||
outmask = ""
|
||||
# Формируем список найденных величин совпадений:
|
||||
# result[x]
|
||||
# x = 0, поиск по неполному совпадению (лайк*), и по длине строки больше исходной
|
||||
# x = 1, поиск по точному совпадению
|
||||
# x = 2, поиск по базе сокращений (по полному)
|
||||
# x = 3, то же, но по краткому
|
||||
out_mask_list = []
|
||||
for ra in result:
|
||||
if ra[0] > 1:
|
||||
if word_len > 2:
|
||||
outmask += 'x'
|
||||
else:
|
||||
outmask += '1'
|
||||
out_mask_list.append('x')
|
||||
else:
|
||||
outmask += str(ra[0])
|
||||
out_mask_list.append(str(ra[0]))
|
||||
|
||||
return outmask
|
||||
return ''.join(out_mask_list)
|
||||
|
||||
def get_type(self):
|
||||
return ", ".join([x for x in self.match_types if self.__dict__[x]])
|
||||
|
||||
Reference in New Issue
Block a user