T-SQL СОДЕРЖИТ цифры и точки (.) - PullRequest
0 голосов
/ 15 января 2019

Давайте рассмотрим User.Note = 'Версия: 3.7.21.1'

SELECT * FROM [USER] WHERE CONTAINS(NOTE, '"3.7.2*"')

=> возвращает что-то

SELECT * FROM [USER] WHERE CONTAINS(NOTE, '"3.7*"')

=> возвращает ничего

Если User.Note = 'Версия: 3.7.21'

SELECT * FROM [USER] WHERE CONTAINS(NOTE, '"3.7*"')

=> возвращает что-то

Если User.Note = 'Версия: 3.72.21'

SELECT * FROM [USER] WHERE CONTAINS(NOTE, '"3.7*"')

=> возвращает ничего

Я не могу понять, как это работает. Он всегда должен что-то возвращать, когда я ищу «3.7 *».

Знаете ли вы, что за этим стоит?

PS: если я заменю цифры буквами, проблем не будет.

Ответы [ 2 ]

0 голосов
/ 16 января 2019

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

В качестве примера я создал небольшую таблицу с тремя указанными вами значениями ...

VALUES (1,'3.7.21.1'),(2,'3.7.21'),(3,'3.72.21')

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

Для меня это возвращает все три значения

SELECT * FROM containstext WHERE CONTAINS(secondid, '"3.7.2*"')

и это возвращает только 3.7.21

SELECT * FROM containstext WHERE CONTAINS(secondid, '"3.7*"')

Итак, давайте запустим это и посмотрим на содержимое полнотекстового индекса

SELECT * FROM sys.dm_fts_index_keywords(db_id('{databasename}'), object_id('{tablename}'))

Для моих результатов (ваши, вероятно, отличаются) у меня есть следующие значения display_term

display_term     document_count
    21              3
    3               3
    3.7.21          1
    7               2
    72              1

Итак, давайте посмотрим на первый критерий поиска '"3.7.2*"' Если я запихну это в sys.dm_fts_parser ...

select * from sys.dm_fts_parser('"3.7.2*"', 1033, NULL, 0)

... это показывает мне, что он ломается со спичками на

3
7
2

Но если я сделаю ...

select * from sys.dm_fts_parser('"3.7*"', 1033, NULL, 0)

Я получаю одно точное совпадение с термином 3.7, и sys.dm_fts_index_keywords сказал мне ранее, что у меня есть только один документ / строка, содержащая 3.7

Вы также можете испытать дополнительную странность, потому что числа 0-9 обычно находятся в системных стоп-словах и могут быть исключены из индекса, потому что они считаются бесполезными. Это может быть то, почему это работает, когда вы переходите на буквы.

Кроме того, я знаю, что вы решили заменить LIKE, но Microsoft предлагает использовать только буквенно-цифровые символы в полнотекстовых индексах и, если вам нужно использовать не алфавитно-цифровые символы в критериях поиска , вы должны использовать как. Возможно, изменить периоды на какую-либо буквенно-цифровую замену, которая не будет использоваться в обычных значениях?

0 голосов
/ 15 января 2019

Содержит будет работать только если столбец в полнотекстовом индексе.Если он не проиндексирован, вам нужно будет использовать следующее:

SELECT * FROM [USER] WHERE NOTE like '3.7%' --or '%3.7%

Вы хотите использовать СОДЕРЖИТ, потому что вы думаете, что это будет быстрее? (Обычно это так)

Документ Microsoftперечисляет все способы, которыми вы можете отформатировать и использовать CONTAINS (11 примеров)

Вот документ Microsoft на CONTAINS

...