Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Contains не ищет подстроку  [new]
RusNafisovich
Member

Откуда:
Сообщений: 7
В базе MSSQL в колонке Name есть значение ООО ПАО Азимут. Его необходимо найти по маске ООО зим.
Я использую полнотекстовый поиск в MSSQL через команду Contains.
Вот мой пример, но он не находит:

SELECT *
FROM Companies
WHERE (Contains((Name), '"ооо*" AND "зим*"'))
ORDER BY Id
OFFSET 0 ROWS FETCH NEXT 50 ROWS ONLY
9 фев 20, 09:17    [22076218]     Ответить | Цитировать Сообщить модератору
 Re: Contains не ищет подстроку  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7332
RusNafisovich,

Азим* найдёте, у вас же слово не начинается с зим*
9 фев 20, 12:07    [22076251]     Ответить | Цитировать Сообщить модератору
 Re: Contains не ищет подстроку  [new]
court
Member

Откуда:
Сообщений: 1932
Владислав Колосов
RusNafisovich,

Азим* найдёте, у вас же слово не начинается с зим*
нее
https://docs.microsoft.com/ru-ru/sql/t-sql/queries/contains-transact-sql?view=sql-server-ver15
<prefix_term>
Указывает совпадение слов или фраз, начинающихся с указанного текста. Префиксные выражения должны заключаться в двойные кавычки (""), и необходимо добавлять звездочку (*) перед закрывающей кавычкой, чтобы совпадал весь текст, начинающийся с простого выражения, заданного до звездочки. Предложение должно быть задано таким образом: CONTAINS (column, '"text*"'). Звездочка заменяет ноль, один или более символов (корневого слова или слов в слове или фразе). Если текст и звездочка не заключены в двойные кавычки и предикат выглядит как CONTAINS (column, 'text*'), то полнотекстовый поиск считает звездочку символом и ищет точное совпадение с text*. Полнотекстовое ядро не найдет слов со звездочкой (*), так как средства разбиения по словам обычно пропускают такие символы.
Если параметр <prefix_term> является фразой, то каждое содержащееся во фразе слово считается отдельным префиксом. Этому запросу, задающему префиксное выражение «local wine*», отвечают все строки с текстом «local winery», «locally wined and dined» и т. д.
9 фев 20, 13:15    [22076271]     Ответить | Цитировать Сообщить модератору
 Re: Contains не ищет подстроку  [new]
court
Member

Откуда:
Сообщений: 1932
Владислав Колосов
RusNafisovich,

Азим* найдёте, у вас же слово не начинается с зим*
или это вы о том, что ТС "А" в начале префикса не дописал (и ищет вхождение "зим", а не префикс "Азим") ?
С этим согласен
9 фев 20, 13:21    [22076273]     Ответить | Цитировать Сообщить модератору
 Re: Contains не ищет подстроку  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7332
court,

да, ТС или опечатался или полагает, что "полнотекстный" означает "поиск любой подстроки".
9 фев 20, 13:51    [22076284]     Ответить | Цитировать Сообщить модератору
 Re: Contains не ищет подстроку  [new]
RusNafisovich
Member

Откуда:
Сообщений: 7
Владислав Колосов,

Да, я не опечатался. даже если значение лежит +79998887766, то я хочу найти по маске 7766, но он у меня не найдет. Каким образом еще можно найти эти строки в рамках MSSQL и без like, так как эти такую подстроку будет искать в 100К записей, то это займет более 5-10 секунд.
10 фев 20, 07:03    [22076491]     Ответить | Цитировать Сообщить модератору
 Re: Contains не ищет подстроку  [new]
Massa52
Member

Откуда:
Сообщений: 371
RusNafisovich,
https://habr.com/ru/company/microsoft/blog/470139/
10 фев 20, 07:58    [22076500]     Ответить | Цитировать Сообщить модератору
 Re: Contains не ищет подстроку  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 30460
Massa52
RusNafisovich,
https://habr.com/ru/company/microsoft/blog/470139/
Это хорошо, если можно выделить префикс.
Но часто бывает нужно искать произвольные подстроки, возможно, у RusNafisovich именно так.
Тогда спасёт только вариант самодельного полнотекстового поиска имени Дмитрия Костылева: Что делать, когда Full-Text бессилен
На SQL.RU есть копия, обсуждалось здесь: Настройка полнотекстового поиска на большой таблице (~2 млрд)
10 фев 20, 08:15    [22076503]     Ответить | Цитировать Сообщить модератору
 Re: Contains не ищет подстроку  [new]
RusNafisovich
Member

Откуда:
Сообщений: 7
alexeyvg,

Решение Костылева - хорошее решение. Я вот подсчитал...
В таблице TableA в поле FieldA хранится значение: +79998887766
Разбиваем на значения:
- 79998887766, 9998887766, 998887766, 98887766, 8887766, 887766, 87766, 7766, 766, 66, 6
Итог: за записью "+79998887766" в таблице TableА будет закреплено 11 записей в таблице TableB для поиска.

Если нужно делать поиск по 4 полям в TableA, то в среднем 11 записей * 4 поля = 44 записей в таблице B.

На текущий момент 100К записей = ~90Мб.
Короче, грубо но если будет отдельная таблица, по которой будет выполняться поиск увеличится в 44 раза. Я правильно понимаю?
10 фев 20, 08:56    [22076509]     Ответить | Цитировать Сообщить модератору
 Re: Contains не ищет подстроку  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 30460
RusNafisovich
Короче, грубо но если будет отдельная таблица, по которой будет выполняться поиск увеличится в 44 раза. Я правильно понимаю?
Правильно, но только в том случае, если у вас в TableA в поле FieldA только уникальные значения, т.е. есть уникальный индекс на FieldA. Ну и то же самое по другим полям. Т.е. все слова во всех полях есть набор уникальных слов.

Тогда да, будет такой оверхед на хранение - 90 мегабайт. Конечно, если база 120 Мб/ то это много, а если база 10 Гб, то что такое 90 Мб?
Но зато будет моментальная выборка по фрагменту слова.
Конечно, если набор слов неуникален, то справочник будет меньше. Во сколько раз - посчитайте по вашим данным.

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

Альтернатива - делать скан.

Других вариантов же нет, просто чисто теоретически, исходя из математических законов, никакой первейший гений программирования не сможет сделать по другому. Либо размер, либо скорость.
10 фев 20, 11:22    [22076606]     Ответить | Цитировать Сообщить модератору
 Re: Contains не ищет подстроку  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7332
RusNafisovich,

Сомневаюсь, что время поиска сильно увеличится. Вы будете искать в словаре и получите ID записей, в которых содержится найденная подстрока. Вот подготовка словаря будет занимать время, возможно, это выгодно делать каким-то фоновым процессом для добавленных в основную таблицу записей.
10 фев 20, 11:22    [22076607]     Ответить | Цитировать Сообщить модератору
 Re: Contains не ищет подстроку  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 30460
Владислав Колосов
RusNafisovich,

Сомневаюсь, что время поиска сильно увеличится.
Как я понял, RusNafisovich имел в виду, что размер сильно увеличится.

Понятно, что скорость тут получится независимая от размера, как у любого индекса.
10 фев 20, 11:31    [22076620]     Ответить | Цитировать Сообщить модератору
 Re: Contains не ищет подстроку  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7332
alexeyvg,

если размер - то да. Иногда надо пожертвовать объемом хранения, чтобы выиграть в скорости получения.
10 фев 20, 11:39    [22076632]     Ответить | Цитировать Сообщить модератору
 Re: Contains не ищет подстроку  [new]
RusNafisovich
Member

Откуда:
Сообщений: 7
Спасибо за идею. Применил такое решение. Пока делаю) О результатах отпишусь
10 фев 20, 15:56    [22076899]     Ответить | Цитировать Сообщить модератору
 Re: Contains не ищет подстроку  [new]
RusNafisovich
Member

Откуда:
Сообщений: 7
Я использовал такой вариант. Если строка "Hello World", то разбивал до такого результата "Hello ello llo lo o World orld rld ld d" и это помогло
18 фев 20, 08:10    [22081827]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить