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

Откуда: Украина
Сообщений: 81
Всем привет.

Есть в принципе достаточно банальная задача - если кратко - есть продукт(таблица с 20 полями), на который может вешаться любое количество аттрибутов описательных - в среднем до 20 штук, которые представляют собой любой тип данных. Продуктов на данный момент порядка 100 000, но база имеет большую перспетиву быстрого роста, необходимо сделать быстрый поиск по атрибутам и по данным самого продукта ... количество одновременных запросов может быть в пределах 100. интересует максимально возможная производительность(это сайт).

что сделано на данный момент - написался job, который раз в сутки в промежуточную таблицу

CREATE TABLE [dbo].[Item_MetaSearch](
	[Item_ID] [int] NOT NULL,
	[Scheme_ID] [int] NULL,
	[ItemType] [tinyint] NULL,
	[MetaDataText] [nvarchar](max) NULL,
	[Title] [nvarchar](255) NULL,
 CONSTRAINT [PK_Item_MetaSearch] PRIMARY KEY CLUSTERED 
(
	[Item_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[Item_MetaSearch]  WITH CHECK ADD  CONSTRAINT [FK_Item_MetaSearch_Item] FOREIGN KEY([Item_ID])
REFERENCES [dbo].[Item] ([ID])
GO
ALTER TABLE [dbo].[Item_MetaSearch] CHECK CONSTRAINT [FK_Item_MetaSearch_Item]
GO
ALTER TABLE [dbo].[Item_MetaSearch]  WITH CHECK ADD  CONSTRAINT [FK_Item_MetaSearch_Scheme] FOREIGN KEY([Scheme_ID])
REFERENCES [dbo].[Scheme] ([ID])
GO
ALTER TABLE [dbo].[Item_MetaSearch] CHECK CONSTRAINT [FK_Item_MetaSearch_Scheme]

сливает все описательные поля(в поле MetaDataText), которые нам интерсны, ну и запущен full text search механизм ...

стоит вопрос - что делать, если меня интересует
1) поиск типа "Texas States Alabama Game"? - причем порядок слов может не совпадать
2) поиск типа "Texa"
3) поиск типа "labama"

для первого пункта сделан Freetext... кусок из кода ...
SELECT Item_ID 
FROM dbo.Item_MetaSearch 
WHERE FREETEXT(MetaDataText, '{0}') 
AND  Scheme_ID = {1}

для второго и третьего прокатил бы Contains
SELECT Item_ID 
FROM dbo.Item_MetaSearch 
WHERE CONTAINS(MetaDataText, '*{0}*') 
AND  Scheme_ID = {1}

но тогда FreeText не вернет вхождения а Contains вернет пусто если не соблюден порядок слов ... на данный момент он вообще выкидывает exception когда я указываю 2 или более слов, то мой query вываливает ошибку ....

Неужели надо как-то комбинироватm freetext + contains? Или есть какие-то дополнительные средства, которые помогут решить проблему? Заранее спасибо.
7 авг 09, 13:47    [7511002]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация текстового поиска по данным - достаточно большой обьем в перспективе  [new]
Glory
Member

Откуда:
Сообщений: 104760
alexxUK


для второго и третьего прокатил бы Contains
SELECT Item_ID 
FROM dbo.Item_MetaSearch 
WHERE CONTAINS(MetaDataText, '*{0}*') 
AND  Scheme_ID = {1}

CONTAINS(и не только он) вообще-то не ищет на вхождение, только по началу.
7 авг 09, 13:54    [7511046]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация текстового поиска по данным - достаточно большой обьем в перспективе  [new]
alexxUK
Member

Откуда: Украина
Сообщений: 81
круто, в итоге первую звезду можно убрать ... :) или вообще убрать 2 звезды ... так как они не будут иметь смысла?
А есть решения по поводу комбинаторики - если надо по любому все 3 варианта оправдать?
я уже думаю разбирать по кол-ву слов и к freetext дописывать что-то формата
[src]
OR Contains(MetaDataText , '{0}*') OR Contains(MetaDataText , '{0}*')
[src]
7 авг 09, 13:58    [7511084]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация текстового поиска по данным - достаточно большой обьем в перспективе  [new]
alexxUK
Member

Откуда: Украина
Сообщений: 81
завершающую "звезду" убирать нельзя = искать не будет все - же ...
Буду шас гуглить и смотреть на ращзличные варинаты запросов с количестком слов 1-5 ... больше вряд ли кто-то будеи вбивать :)
7 авг 09, 14:05    [7511131]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация текстового поиска по данным - достаточно большой обьем в перспективе  [new]
Opengls
Member

Откуда:
Сообщений: 16
неправда, CONTAINS и вхождение тоже ищет
7 авг 09, 14:37    [7511339]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация текстового поиска по данным - достаточно большой обьем в перспективе  [new]
Glory
Member

Откуда:
Сообщений: 104760
Opengls
неправда, CONTAINS и вхождение тоже ищет

И чем вы это можете доказать ?
7 авг 09, 14:38    [7511342]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация текстового поиска по данным - достаточно большой обьем в перспективе  [new]
alexxUK
Member

Откуда: Украина
Сообщений: 81
contains действительно ищет только по префиксу ...
http://msdn.microsoft.com/ru-ru/library/cc879300.aspx

вычитал, что в FreeText более ресурсоемкий поисковик - что по возможности надо пытаться использовать Contains.

В итоге многословие можно разбить на

SELECT Item_ID, Scheme_ID 
FROM dbo.Item_MetaSearch 
WHERE CONTAINS(MetaDataText, N' "Texas*" OR "State*" OR "Alabama*" OR "Game*" ')

вместо ...

SELECT Item_ID, Scheme_ID 
FROM dbo.Item_MetaSearch 
WHERE FREETEXT(MetaDataText, 'Texas States Alabama Game'); 

но опять же возникает проблема если я в поиске укажу неправильный падеж - тогда для Contains надо указывать FORMSOF ... что опять же накручивает логику составления Query. ...

в итоге пример надо будет преобразовывать до
SELECT Item_ID, Scheme_ID 
FROM dbo.Item_MetaSearch 
WHERE CONTAINS(MetaDataText, N' "Texas" OR "State*" OR "Alabama*" OR "Game*" OR
FORMSOF(INFLECTIONAL, Texas) OR FORMSOF(INFLECTIONAL, State) OR FORMSOF(INFLECTIONAL, Alabama) OR FORMSOF(INFLECTIONAL, Game)')


неужели никто не сталкивался с проблемой, или все используют Lucene?

Кстати - во избежание неявного преобразования типов данных во время поиска - поля таблицы следует определять как nvarchar ...
7 авг 09, 15:34    [7511663]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация текстового поиска по данным - достаточно большой обьем в перспективе  [new]
Opengls
Member

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

SET @СтрокаПоиска = "иванов* ~ владимир* ~ николаевич*" OR "иванов*" ~ "в" ~ "н"
CONTAINS([f_Note], @СтрокаПоиска)

находит следующее

строка 1
Иванов Владимир Николаевич % Дт. Cirr (кл-ты) RUR ( вклад N xxxxxxxxxxxxxxxx ): - с суммы xxxx.20 - 0.4900% годовых - за xx день

строка 2
З/П 04 05 Иванов Владимир Николаевич

строка 3
Ссылка: xxxxxxxxxxx Окончательный расчет при увольнении на xxxxxxxxxxxxxxxxxxxxxxxx.Иванов Владимир Николаевич xxxxxx Негосударственное xxxxx пред

строка 4
Г/К Иванов Владимир Николаевич Гашение кредита

строка 5
USD прод. вал. за руб. Курс конверсии: 27.860000000 Курс конверсии "офиц.": 27.758600000 С суммы: 270.00 паспорт,xxxxxxxx Иванов В.Н.

строка 6
Иванов Владимир Николаевич % Дт. Cirr (кл-ты) RUR ( вклад N ххххххххххххххххх ): - с суммы хххх.86 - 0.5000% годовых - за хх дней
10 авг 09, 08:41    [7515909]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация текстового поиска по данным - достаточно большой обьем в перспективе  [new]
Glory
Member

Откуда:
Сообщений: 104760
Opengls
Glory,

SET @СтрокаПоиска = "иванов* ~ владимир* ~ николаевич*" OR "иванов*" ~ "в" ~ "н"
CONTAINS([f_Note], @СтрокаПоиска)

находит следующее

А вы разницу между "вхождение в строку" и "начало строки" понимаете ?
Где в вашем примере поиск на вхождение в подстроки в строку ?
10 авг 09, 10:38    [7516204]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить