Существует ли способ отфильтровать django queryset на основе строкового подобия (а-ля Python difflib)?

У меня есть потребность соответствовать холоду, ведет против базы данных наших клиентов.

Приведение, прибывшее от стороннего поставщика оптом (тысячи записей) и продажи, спрашивает нас к (в их словах), "отфильтровывают наши клиенты", таким образом, они не пытаются продать нашу услугу установленному клиенту.

Очевидно, в приведении существуют орфографические ошибки. 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. Спасибо, вид сэр.

8
задан Community 23 May 2017 в 11:45
поделиться

1 ответ

soundex вам не поможет, потому что это фонетический алгоритм. Джо и Джозеф не похожи фонетически, поэтому soundex не пометит их как похожие.

Вы можете попробовать Levenshtein distance, который реализован в PostgreSQL. Возможно, в вашей базе данных тоже, а если нет, то вы должны быть в состоянии написать хранимую процедуру, которая вычислит расстояние между двумя строками и использует его в своих вычислениях.

2
ответ дан 6 December 2019 в 00:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: