У меня есть потребность соответствовать холоду, ведет против базы данных наших клиентов.
Приведение, прибывшее от стороннего поставщика оптом (тысячи записей) и продажи, спрашивает нас к (в их словах), "отфильтровывают наши клиенты", таким образом, они не пытаются продать нашу услугу установленному клиенту.
Очевидно, в приведении существуют орфографические ошибки. Charles становится Charlie, Joseph становится Joe, и т.д. Таким образом, я не могу действительно просто сделать фильтра, выдерживающего сравнение lead_first_name к client_first_name и т.д.
Я должен использовать своего рода строковый механизм подобия.
Прямо сейчас я использую прекрасный difflib для сравнения имени и фамилии lead со списком, сгенерированным с Client.objects.all()
. Это работает, но из-за числа клиентов это имеет тенденцию быть медленным.
Я знаю, что большинство sql баз данных имеет функции различия и soundex. Посмотрите мой тест его в обновлении ниже - это не работает, а также difflib.
Есть ли другое решение? Существует ли лучшее решение?
Править:
Soundex, по крайней мере, в моем дб, не ведет себя, а также difflib.
Вот простой тест - ищут "Joe Lopes" в таблице, содержащей "Joseph Lopes":
with temp (first_name, last_name) as (
select 'Joseph', 'Lopes'
union
select 'Joe', 'Satriani'
union
select 'CZ', 'Lopes'
union
select 'Blah', 'Lopes'
union
select 'Antonio', 'Lopes'
union
select 'Carlos', 'Lopes'
)
select first_name, last_name
from temp
where difference(first_name+' '+last_name, 'Joe Lopes') >= 3
order by difference(first_name+' '+last_name, 'Joe Lopes')
Вышеупомянутые возвраты "Joe Satriani" как единственное соответствие. Даже сокращение порога подобия к 2 не возвращает "Joseph Lopes" как потенциальное соответствие.
Но difflib делает намного лучшее задание:
difflib.get_close_matches('Joe Lopes', ['Joseph Lopes', 'Joe Satriani', 'CZ Lopes', 'Blah Lopes', 'Antonio Lopes', 'Carlos Lopes'])
['Joseph Lopes', 'CZ Lopes', 'Carlos Lopes']
Редактирование после ответа gruszczy:
Прежде, чем записать мое собственное, я искал и нашел реализацию T-SQL расстояния Левенштейна в хранилище всех знаний.
В тестировании его он все еще не сделает лучшего задания соответствия, чем difflib.
Который привел меня к исследованию, какой алгоритм находится позади difflib. Это, кажется, измененная версия алгоритма Ratcliff-Obershelp.
К несчастью я, может казаться, не нахожу некоторую другую добрую душу, которая уже создала реализацию T-SQL на основе difflib's... Я попробую силы в нем, когда я буду мочь.
Если никто больше не придумает лучший ответ в ближайшие дни, то я предоставлю его gruszczy. Спасибо, вид сэр.
soundex
вам не поможет, потому что это фонетический алгоритм. Джо и Джозеф не похожи фонетически, поэтому soundex не пометит их как похожие.
Вы можете попробовать Levenshtein distance, который реализован в PostgreSQL. Возможно, в вашей базе данных тоже, а если нет, то вы должны быть в состоянии написать хранимую процедуру, которая вычислит расстояние между двумя строками и использует его в своих вычислениях.