Поиск телефонных номеров - поиск номера с добавочным номером и без него - PullRequest
4 голосов
/ 04 мая 2010

У меня есть таблица с около 130 000 записей с телефонными номерами. Числа все отформатированы так: +4311234567. Номера всегда включают международный код страны, код локальной зоны, а затем номер телефона и иногда добавочный номер.

Существует веб-служба, которая проверяет номер звонящего в таблице. Этот сервис уже работает. Но теперь клиент хочет, чтобы и в случае, если кто-то позвонит из компании, номер которой уже есть в базе данных, но не его добавочный номер, эта служба вернет некоторый результат.

Пример для табл.

   **id** | **telephonenumber**    | **name**   
|    1    | +431234567             | company A  
|    2    | +431234567890          |  employee in company A  
|    3    | +4398765432            | company b 

сейчас, если кто-то из компании A звонит с другим добавочным номером, например +43123456777, чем он должен вернуть id1. Но проблема в том, что я не знаю, сколько цифр у расширений. Может содержать 3,4 или более цифр.

Существуют ли какие-либо шаблоны для сопоставления строк?

Данные хранятся в базе данных sql2005.

Спасибо

EDIT:
Номера телефонов, которые я получаю от системы crm. Я разговаривал с администратором crm, и он пытается отправить мне данные в другом формате.

   **id** | **telephonenumber** |**extension**   | **name**   
|    1    | +431234567          |                | company A  
|    2    | +431234567          |      890       |  employee in company A  
|    3    | +4398765432         |                | company b 

Ответы [ 7 ]

4 голосов
/ 04 мая 2010

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

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

2 голосов
/ 04 мая 2010

Учитывая, что количество цифр в добавочном номере может быть разным для каждой компании и количество цифр в номере может быть разным для каждой страны и кода города, это сложная задача для эффективного решения ,

Даже если вы разбили таблицу данных на базовый номер и добавочный номер, вам все равно придется разделить входящий номер на базовый номер и добавочный номер, что, на мой взгляд, усложняет ситуацию.

Я бы хотел попробовать:

Оригинальный формат

  1. Попробуйте сопоставить входящий номер с базой данных.
    • Если он соответствует одной записи, у вас есть ответ - конкретный человек.
    • Если он соответствует более чем одной записи, что-то пошло не так, поэтому не удалось.
    • В противном случае вы должны найти компанию:
  2. Снимите конечную цифру с входящего номера и попробуйте снова сопоставить ее с базой данных.
    • Если количество цифр падает ниже порогового значения (вероятно, 6 цифр), то ваш поиск, вероятно, должен завершиться неудачей. Это просто для ограничения количества поисков в базе данных, которые не будут найдены.
    • Если он не соответствует ни одной записи, вам нужно повторить этот шаг.
    • Если он соответствует более чем одной записи, значит, что-то пошло не так, поэтому не удалось.
    • Если он соответствует ровно одной записи, у вас будет следующий лучший ответ - компания.

Например, поиск "+43123456777":

  • + 43123456777 соответствует 0 записей.
  • + 4312345677 соответствует 0 записей.
  • + 431234567 соответствует 1 записи: "Компания A"

Основным режимом сбоя этого подхода является наличие у компании добавочных номеров переменной длины. Например, рассмотрим, что произойдет, если и 431234567890, и 43123456789 являются действительными числами, но только второй находится в базе данных. Если входящий номер 431234567890, то 43123456789 будет совпадать с ошибкой.

Сплит формат

Это немного сложнее, но надежнее.

  1. Попробуйте сопоставить входящий номер с базой данных.
    • Если он соответствует одной записи, у вас есть ответ - компания.
    • Если он соответствует более чем одной записи, сопоставьте запись без расширения, и вы нашли компанию.
    • В противном случае вам нужно найти номер базовой компании и добавочный номер:
  2. Снимите конечную цифру с входящего номера и попробуйте снова сопоставить ее с базой данных.
    • Если количество цифр падает ниже порогового значения (вероятно, 6 цифр), то ваш поиск, вероятно, должен завершиться неудачей. Это просто для ограничения количества поисков в базе данных, которые не будут найдены.
    • Если он не соответствует ни одной записи, вам нужно повторить этот шаг.
    • Если он соответствует одной записи, значит, вы нашли свой ответ - компания.
    • Если он соответствует более чем одной записи, то вы нашли базовый номер компании и, таким образом, теперь знаете расширение, поэтому можете попытаться найти конкретного человека:
  3. Снимите базовый номер с начала исходного входящего номера и используйте его для поиска расширений записей с этим базовым номером.
    • Если он соответствует ровно одной записи, вы нашли конкретного человека.
    • Если это не соответствует конкретному человеку, сопоставьте запись без расширения, и вы нашли компанию.

Например, поиск "+43123456777":

  • + 43123456777 соответствует 0 записей.
  • + 4312345677 соответствует 0 записей.
  • + 431234567 соответствует 2 записям: "empty: Company A" & "890: сотрудник компании A"
  • В этих двух совпадениях "77" ничего не соответствует, поэтому верните пустое расширение: "Компания A".

Замечания по реализации

Этот алгоритм, как отмечено выше, имеет некоторые проблемы с эффективностью. Если поиск в базе данных является дорогостоящим, он имеет линейную стоимость, связанную с длиной телефонного номера, особенно в случае, когда в базе данных нет похожих номеров (например, если входящий номер из Казахстана, но нет Казахстана) числа в базе данных * 8 ').

Вы можете относительно легко добавить некоторые оптимизации. Если большинство компаний, с которыми вы работаете, используют расширения из 3 или 4 цифр, вы можете начать с удаления, скажем, 4 цифр с конца, а затем выполнить двоичный код, пока не найдете ответ. Это уменьшит число из 15 цифр до 4 или 5 во многих случаях и не более 6 поисков.

Кроме того, каждый раз, когда вы сужаете выбор, вы можете выбирать только в пределах предыдущего выбора, а не выбирать во всей базе данных.

Дополнительные замечания по реализации

Наконец-то выяснив, как работает Неразумный ответ , я вижу, что это гораздо более простое, более элегантное решение. Хотелось бы мне хотя бы просто найти номер базы данных во входящем номере, а не наоборот.

Меня беспокоит только то, что выполнение этого для каждого telephonenumber в базе данных может привести к чрезмерным нагрузкам на сервер. Я бы предложил сравнить это решение с максимальной нагрузкой и посмотреть, не вызовет ли оно проблем. Если нет, хорошо - используйте это. Если это произойдет, рассмотрите возможность реализации простой формы моего алгоритма и повторного проведения стресс-тестов. Если производительность все еще слишком низкая, попробуйте мое предложение двоичного поиска.

2 голосов
/ 04 мая 2010

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

Если вы получите номер телефона, например +431234567891, из идентификатора вызывающего абонента, то

SELECT name, id
FROM Table
WHERE CHARINDEX(telephonenumber, "+431234567891") > 0;

вернет компанию, а в случае +431234567890 вернет 2 записи

  • компания
  • фактическое продление

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

Предварительная обработка данных лучше (с точки зрения производительности), но для этого вам нужно описать данные более подробно, например:

  • являются расширениями только 3 и 4 цифры,
  • это базовый номер всегда 9 или 10 цифр,
  • всегда ли у вас есть хотя бы один добавочный номер для компаний с добавочными номерами и т. Д ...
1 голос
/ 04 мая 2010

Если вы имеете дело с телефонными номерами из разных стран, это будет практически невозможно. Длина часто меняется, даже в пределах одной страны. Если вы знаете, какой будет длина (или вы хотите сохранить список, подобный тому, который указал ChrisW), вы можете использовать функцию ВЛЕВО (поле, x), чтобы обрезать номер телефона, прежде чем искать номер телефона компании. Обратите внимание, что если вы выполняете объединение, оно, вероятно, будет работать намного медленнее, поскольку должно запускать функцию в каждой строке.

1 голос
/ 04 мая 2010

Что ж, я понимаю систему телефонных номеров так, что не может быть двух действительных / полных номеров, где один является префиксом другого. Обычная шутка здесь - выдавать ваш номер 11 05 32 или около того, где 110 - номер экстренной полиции Германии.

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

  • Базовый номер (самый короткий)
  • Прямой номер плюс добавочный номер (все более длинные)

Я бы пометил их в базе данных для более быстрого поиска, если это возможно.

Этот подход не подходит для случая, когда у вас есть общее расширение по умолчанию. Здесь многие компании выдают что-то вроде 1234567-0 в качестве внешнего номера, где 0 можно заменить на 2-4-значный добавочный номер. В этих случаях мой подход был бы неудачным - для ваших данных примера это сработало бы?

1 голос
/ 04 мая 2010

Количество цифр в добавочном номере зависит от АТС. Количество цифр в коде города + номер телефона зависит от страны / оператора.

Один из способов сделать это - определить дополнительные правила, например ...

+ 43123 | 12

... сказать, что все, что начинается с +43123, является 12-значным числом, и что все, кроме этого, является расширением: это позволяет вам использовать (настраиваемые, а не жестко запрограммированные) данные, чтобы указать, где начнется расширение .

Другой способ может заключаться в том, чтобы настаивать на том, что для любых записей числа с расширением должен быть также соответствующий номер без расширения, как показано в вашем примере с «компанией А».

0 голосов
/ 04 мая 2010

Это будет невозможно без дополнительной информации: если ваша таблица структурирована, как указано выше, система не имеет возможности узнать, какая часть является базовым номером, а какая - добавочным. Таким образом, он вернул бы «company b» для любого (неизвестного) номера, начинающегося с «+439».

РЕДАКТИРОВАТЬ (@MarkBooth)

Я подтверждаю, что это невозможно без дополнительной информации. Просто для простоты: скажем, у нас есть следующая информация в нашей базе данных

...
+43316852132 - ....
+433168731 - Company A (reception)
+433168739999 - Company A, Mr. X
+433168911321 - ....
...

Структура этих чисел составляет +43 (316) 873-1, чего не знает Программа. Поэтому, если звонит номер +43316872133 (+43 (316) 87 21 33 со структурой) (которого нет в базе данных), вы (и, следовательно, ваше программное обеспечение :)) не можете определить, принадлежит ли он компании А или нет, без дальнейшего информация.

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

...