Примечание: Я имею в использовании функции поиска полнотекстовой SQL для , СОДЕРЖИТ положение и все - * является подстановочным в полном тексте,% только для статей LIKE.
Сейчас я читал в нескольких местах, что поиск с «подстановочными символами» (например, использование «* overflow» для совпадения с «stackoverflow») не поддерживается в MS SQL. Я рассматриваю возможность использования функции CLR для добавления соответствия регулярному выражению , но мне любопытно посмотреть, какие другие решения могут быть у людей.
Дополнительная информация : Вы можете добавить звездочку только в конце слова или фразы. - вместе с моим эмпирическим опытом: при сопоставлении «myvalue» «my *» работает, но «(звездочка) значение» не возвращает совпадений, когда выполняется запрос, такой как:
SELECT * FROM TABLENAME WHERE CONTAINS(TextColumn, '"*searchterm"');
Таким образом, моя потребность в обходном пути. Я использую поиск на своем сайте только на реальной поисковой странице - поэтому он должен работать в основном так же, как работает Google (в глазах пользователя типа Джо Сикспака). Не так сложно, но такой матч действительно не должен провалиться.
Подстановочный знак в SQL Server является %
знаком, и он работает просто отлично, ведущий, конечный или другой.
Тем не менее, если вы собираетесь заниматься каким-либо серьезным полнотекстовым поиском, я бы подумал об использовании возможностей полнотекстового индекса. Использование %
и _
подстановочные знаки приведут к серьезному снижению производительности вашей базы данных.
% Соответствует любому количеству символов _ Соответствует одному символу
Я никогда не использовал полнотекстовое индексирование, но вы можете выполнять довольно сложные и быстрые поисковые запросы, просто используя встроенные строковые функции T-SQL.
Следует иметь в виду, что передовые подстановочные запросы имеют значительный выигрыш в производительности по сравнению с другими подстановочными знаками.
Проблема с ведущими символами подстановки: они не могут быть проиндексированы, поэтому вы выполняете полное сканирование таблицы.
Из электронной документации по SQL Server:
Чтобы написать полнотекстовые запросы в Microsoft SQL Server 2005, вы должны научиться использовать предикаты CONTAINS и FREETEXT Transact-SQL, а также функции с набором строк CONTAINSTABLE и FREETEXTTABLE.
Это означает, что все запросы, написанные выше с% и _, не являются допустимыми полнотекстовыми запросами.
Вот пример того, как выглядит запрос при вызове функции CONTAINSTABLE.
ВЫБЕРИТЕ RANK, * FROM TableName, CONTAINSTABLE (TableName, *, '"* WildCard"') searchTable WHERE [KEY] = TableName.pk ЗАКАЗАТЬ НА searchTable.RANK DESC
Чтобы функция CONTAINSTABLE знала, что я использую поиск по шаблону, мне нужно заключить его в двойные кавычки. Я могу использовать подстановочный знак * в начале или конце. Есть много других вещей, которые вы можете сделать, когда создаете строку поиска для функции CONTAINSTABLE. Вы можете искать слово рядом с другим словом, искать слова со словами (диск = диски, водил, водил и водил) и искать синоним другого слова (у металла могут быть синонимы, такие как алюминий и сталь).
Я просто создал таблицу, поместил в нее полнотекстовый индекс и выполнил пару тестовых поисков, и у меня не возникло проблем, поэтому поиск по шаблону работает как задумано.
[Обновить]
Я вижу, что вы обновили свой вопрос и знаете, что вам нужно использовать одну из функций.
Вы все еще можете искать с подстановочным знаком в начале, но если слово не является полным словом после подстановочного знака, вам нужно добавить еще один подстановочный знак в конце.
Example: "*ildcar" will look for a single word as long as it ends with "ildcar".
Example: "*ildcar*" will look for a single word with "ildcar" in the middle, which means it will match "wildcard". [Just noticed that Markdown removed the wildcard characters from the beginning and ending of my quoted string here.]
[Обновление № 2]
Дейв Уорд - Использование подстановочного знака с одной из функций не должно быть огромным хитом перфорации. Если я создал строку поиска только с «*», он не вернет все строки, в моем тестовом случае он вернул 0 записей.
Когда дело доходит до полнотекстового поиска, за мои деньги ничто не сравнится с Lucene . Существует порт .Net доступен , который совместит с индексами , созданных с версией Java.
Нужно немного поработать над тем, чтобы создать / поддерживать индексы, но скорость поиска просто фантастическая, и вы можете создавать всевозможные интересные запросы. Даже скорость индексации довольно хорошая - мы просто полностью перестраиваем наши индексы один раз в день и не беспокоимся об их обновлении.
В качестве примера, эта функциональность поиска основана на Lucene.Net.
Только к вашему сведению, Google не выполняет поиск или усечение подстрок, ни правых, ни левых. У них есть символ подстановки *, чтобы найти неизвестные слова во фразе, но не слово.
Google, наряду с большинством полнотекстовых поисковых систем, устанавливает инвертированный индекс на основе алфавитного порядка слов со ссылками на их исходные документы. Двоичный поиск быстро работает даже для огромных индексов. Но в этом случае действительно очень трудно выполнить усечение влево, потому что оно теряет преимущество индекса.
Обходной путь только для лидирующего группового символа:
- сохранить перевернутый текст в другом поле (или в материализованном представлении)
- создать полнотекстовый индекс для этого столбца
найти перевернутый текст с помощью *
SELECT * FROM TABLENAME WHERE CONTAINS(TextColumnREV, '"mrethcraes*"');
Конечно, есть много недостатков, только для быстрого обхода ...
Не говоря уже о CONTAINSTABLE ...
Можно использовать подстановочный знак «*» в конце слова или фразы (поиск по префиксу).
Например, этот запрос найдет все «данные», «базы данных», «базы данных» ...
SELECT * FROM SomeTable WHERE CONTAINS(ColumnName, '"datab*"')
Но, к сожалению, невозможно выполнить поиск с лидирующим символом подстановки.
Например, этот запрос не найдет «базу данных»
SELECT * FROM SomeTable WHERE CONTAINS(ColumnName, '"*abase"')
Чтобы внести ясность в эту ветку, после моего тестирования на 2008 R2 Франьо правильно сказал выше. При работе с полнотекстовым поиском, по крайней мере, при использовании фразы CONTAINS, вы не можете использовать ведущий , только трейлинг функционально. * подстановочный знак, а не% в полном тексте.
Некоторые предположили, что * игнорируется. Похоже, что это не так, мои результаты показывают, что конечная функциональность * работает. Я думаю, что ведущие * игнорируются двигателем.
Однако моя дополнительная проблема заключается в том, что тот же запрос с завершающим символом *, использующий полный текст с подстановочными знаками, работал относительно быстро в 2005 году (20 секунд) и замедлился до 12 минут после переноса базы данных в 2008 R2. Похоже, что по крайней мере еще один пользователь имел схожие результаты, и он создал пост на форуме, который я добавил к ... FREETEXT все еще работает быстро, но что-то "кажется" изменилось в связи с тем, что процессы 2008 тянулись * в CONTAINS. Они дают всевозможные предупреждения в Upgrade Advisor о том, что они «улучшили» полный текст, чтобы ваш код мог сломаться, но, к сожалению, они не дают вам каких-либо конкретных предупреждений об определенном устаревшем коде и т. Д. ... просто отказ от ответственности, что они изменили его, Используйте на свой риск.
http://social.msdn.microsoft.com/Forums/ar-SA/sqlsearch/thread/7e45b7e4-2061-4c89-af68-febd668f346c
Может быть, это самый близкий попадание MS в связи с этими проблемами ... http://msdn.microsoft.com/en-us/library/ms143709.aspx
В качестве параметра хранимой процедуры вы можете использовать его как:
ALTER procedure [dbo].[uspLkp_DrugProductSelectAllByName]
(
@PROPRIETARY_NAME varchar(10)
)
as
set nocount on
declare @PROPRIETARY_NAME2 varchar(10) = '"' + @PROPRIETARY_NAME + '*"'
select ldp.*, lkp.DRUG_PKG_ID
from Lkp_DrugProduct ldp
left outer join Lkp_DrugPackage lkp on ldp.DRUG_PROD_ID = lkp.DRUG_PROD_ID
where contains(ldp.PROPRIETARY_NAME, @PROPRIETARY_NAME2)
Возможно, следующая ссылка предоставит окончательный ответ на это использование подстановочных знаков: Выполнение поиска подстановочных знаков FTS .
Обратите внимание на отрывок, в котором говорится: «Однако, если вы укажете« Chain »или« Ch ain », вы не получите ожидаемый результат. Звездочка будет рассматриваться как обычный знак пунктуации, а не как символ подстановки».
Если у вас есть доступ к списку слов механизма полнотекстового поиска, вы можете выполнить поиск в этом списке по принципу «нравится» и сопоставить базу данных с найденными словами, например, таблицу «слова» со следующими словами:
pie
applepie
spies
cherrypie
dog
cat
Чтобы сопоставить все слова, содержащие «pie» в этой базе данных в таблице fts «full_text» с полем «text»:
to-match <- SELECT word FROM words WHERE word LIKE '%pie%'
matcher = ""
a = ""
foreach(m, to-match) {
matcher += a
matcher += m
a = " OR "
}
SELECT text FROM full_text WHERE text MATCH matcher