Mở rộng ý tưởng của Ishmael, đó không phải là giải pháp cuối cùng, nhưng tôi nghĩ đó là một cách tốt để bắt đầu.
Đầu tiên, chúng ta cần lấy danh sách các từ đã được truy xuất bằng công cụ toàn văn:
declare @SearchPattern nvarchar(1000) = 'FORMSOF (INFLECTIONAL, " ' + @SearchString + ' ")'
declare @SearchWords table (Word varchar(100), Expansion_type int)
insert into @SearchWords
select distinct display_term, expansion_type
from sys.dm_fts_parser(@SearchPattern, 1033, 0, 0)
where special_term = 'Exact Match'
Đã có khá nhiều thứ có thể mở rộng, ví dụ như mẫu tìm kiếm khá cơ bản; Ngoài ra, có lẽ có nhiều cách tốt hơn để lọc ra những từ bạn không cần, nhưng ít nhất nó cung cấp cho bạn danh sách các từ gốc, v.v. sẽ được đối sánh bằng tìm kiếm toàn văn.
Sau khi nhận được kết quả bạn cần, bạn có thể sử dụng RegEx để phân tích cú pháp thông qua tập hợp kết quả (hoặc tốt nhất là chỉ một tập hợp con để tăng tốc độ, mặc dù tôi vẫn chưa tìm ra cách tốt để làm như vậy). Đối với điều này, tôi chỉ cần sử dụng hai vòng lặp while và một loạt các bảng và biến tạm thời:
declare @FinalResults table
while (select COUNT(*) from @PrelimResults) > 0
begin
select top 1 @CurrID = [UID], @Text = Text from @PrelimResults
declare @TextLength int = LEN(@Text )
declare @IndexOfDot int = CHARINDEX('.', REVERSE(@Text ), @TextLength - dbo.RegExIndexOf(@Text, '\b' + @FirstSearchWord + '\b') + 1)
set @Text = SUBSTRING(@Text, case @IndexOfDot when 0 then 0 else @TextLength - @IndexOfDot + 3 end, 300)
while (select COUNT(*) from @TempSearchWords) > 0
begin
select top 1 @CurrWord = Word from @TempSearchWords
set @Text = dbo.RegExReplace(@Text, '\b' + @CurrWord + '\b', '<b>' + SUBSTRING(@Text, dbo.RegExIndexOf(@Text, '\b' + @CurrWord + '\b'), LEN(@CurrWord) + 1) + '</b>')
delete from @TempSearchWords where Word = @CurrWord
end
insert into @FinalResults
select * from @PrelimResults where [UID] = @CurrID
delete from @PrelimResults where [UID] = @CurrID
end
Một số lưu ý:
1. Các vòng lặp while lồng nhau có lẽ không phải là cách hiệu quả nhất để làm điều đó, tuy nhiên, không có điều gì khác cần lưu ý. Nếu tôi sử dụng con trỏ, về cơ bản nó sẽ giống như vậy?
2. @FirstSearchWord
ở đây để chỉ trường hợp đầu tiên trong văn bản của một trong những từ tìm kiếm ban đầu, vì vậy về cơ bản văn bản bạn đang thay thế sẽ chỉ nằm trong phần tóm tắt. Một lần nữa, nó là một phương pháp khá cơ bản, một số loại thuật toán tìm kiếm cụm văn bản có thể sẽ hữu ích.
3. Để có được RegEx ngay từ đầu, bạn cần các hàm CLR do người dùng xác định.