Как заставить ведущие полнотекстовые поисковые запросы работать в SQL Server?

Примечание: Я имею в использовании функции поиска полнотекстовой SQL для , СОДЕРЖИТ положение и все - * является подстановочным в полном тексте,% только для статей LIKE.

Сейчас я читал в нескольких местах, что поиск с «подстановочными символами» (например, использование «* overflow» для совпадения с «stackoverflow») не поддерживается в MS SQL. Я рассматриваю возможность использования функции CLR для добавления соответствия регулярному выражению , но мне любопытно посмотреть, какие другие решения могут быть у людей.

Дополнительная информация : Вы можете добавить звездочку только в конце слова или фразы. - вместе с моим эмпирическим опытом: при сопоставлении «myvalue» «my *» работает, но «(звездочка) значение» не возвращает совпадений, когда выполняется запрос, такой как:

SELECT * FROM TABLENAME WHERE CONTAINS(TextColumn, '"*searchterm"');

Таким образом, моя потребность в обходном пути. Я использую поиск на своем сайте только на реальной поисковой странице - поэтому он должен работать в основном так же, как работает Google (в глазах пользователя типа Джо Сикспака). Не так сложно, но такой матч действительно не должен провалиться.

6.08.2008 13:52:29
13 ОТВЕТОВ

Подстановочный знак в SQL Server является %знаком, и он работает просто отлично, ведущий, конечный или другой.

Тем не менее, если вы собираетесь заниматься каким-либо серьезным полнотекстовым поиском, я бы подумал об использовании возможностей полнотекстового индекса. Использование %и _подстановочные знаки приведут к серьезному снижению производительности вашей базы данных.

3
18.03.2016 10:59:54

% Соответствует любому количеству символов _ Соответствует одному символу

Я никогда не использовал полнотекстовое индексирование, но вы можете выполнять довольно сложные и быстрые поисковые запросы, просто используя встроенные строковые функции T-SQL.

-1
6.08.2008 14:00:57

Следует иметь в виду, что передовые подстановочные запросы имеют значительный выигрыш в производительности по сравнению с другими подстановочными знаками.

3
6.08.2008 14:03:59

Проблема с ведущими символами подстановки: они не могут быть проиндексированы, поэтому вы выполняете полное сканирование таблицы.

16
6.08.2008 14:07:59

Из электронной документации по 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 записей.

1
6.08.2008 15:29:50
Я не могу воспроизвести это в SQL 2005. Использование * в начале строки поиска, как показано, не приводит ни к каким строкам.
gregmac 15.09.2009 16:03:46
Не уверен, почему это помечено как ответ, потому что это не совсем точно. Подстановочный знак не работает при полнотекстовом поиске. Проверено это в SQL Server 2008 для полнотекстового индекса с использованием функцииtabletable. Посмотрите ответ / сообщение Майкла Стума для понимания почему.
Jagd 4.04.2011 18:44:20
@Jagd - тогда дайте лучший ответ.
Greg Hurlman 6.10.2011 18:57:08
Согласился с @Jagd, это должно быть отклонено и не отмечено как ответ. OP явно говорит об индексах FT (следовательно, * как подстановочный знак), и просто и неправильно указывать, что * работает как префикс в операции с индексом FT. Рад быть доказанным неправым, но не думаю, что я.
John B 23.12.2011 00:14:28
ведущий подстановочный знак не работает в sqlserver, поэтому этот ответ неверен, если смотреть с точки зрения исходного вопроса.
Evert 19.04.2013 11:54:28

Когда дело доходит до полнотекстового поиска, за мои деньги ничто не сравнится с Lucene . Существует порт .Net доступен , который совместит с индексами , созданных с версией Java.

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

В качестве примера, эта функциональность поиска основана на Lucene.Net.

0
8.08.2008 15:34:28

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

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

1
16.09.2008 00:22:38

Обходной путь только для лидирующего группового символа:

  • сохранить перевернутый текст в другом поле (или в материализованном представлении)
  • создать полнотекстовый индекс для этого столбца
  • найти перевернутый текст с помощью *

    SELECT * 
    FROM TABLENAME 
    WHERE CONTAINS(TextColumnREV, '"mrethcraes*"');

Конечно, есть много недостатков, только для быстрого обхода ...

Не говоря уже о CONTAINSTABLE ...

26
18.03.2016 10:27:55

Можно использовать подстановочный знак «*» в конце слова или фразы (поиск по префиксу).

Например, этот запрос найдет все «данные», «базы данных», «базы данных» ...

SELECT * FROM SomeTable WHERE CONTAINS(ColumnName, '"datab*"')

Но, к сожалению, невозможно выполнить поиск с лидирующим символом подстановки.

Например, этот запрос не найдет «базу данных»

SELECT * FROM SomeTable WHERE CONTAINS(ColumnName, '"*abase"')
10
26.11.2008 09:22:02
Я провел довольно много поисков именно этой вещи, и, к сожалению, большинство людей ошибаются и думают, что они могут сделать поиск по шаблону. Поиск с использованием подстановочных знаков не работает. Франьо правильно, подстановочный знак должен быть в конце поисковой фразы. Я использую SQL 2008 R2. Он вообще не находит его (он не выполняет сканирование таблицы или индекса и не находит его - он вообще его не находит)
astrosteve 2.03.2016 17:26:30

Чтобы внести ясность в эту ветку, после моего тестирования на 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

4
6.10.2011 18:17:56

В качестве параметра хранимой процедуры вы можете использовать его как:

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)
1
18.03.2016 10:29:17

Возможно, следующая ссылка предоставит окончательный ответ на это использование подстановочных знаков: Выполнение поиска подстановочных знаков FTS .

Обратите внимание на отрывок, в котором говорится: «Однако, если вы укажете« Chain »или« Ch ain », вы не получите ожидаемый результат. Звездочка будет рассматриваться как обычный знак пунктуации, а не как символ подстановки».

0
18.10.2016 17:34:27

Если у вас есть доступ к списку слов механизма полнотекстового поиска, вы можете выполнить поиск в этом списке по принципу «нравится» и сопоставить базу данных с найденными словами, например, таблицу «слова» со следующими словами:

    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
0
2.07.2018 14:20:02