SQL Server databases are full-text enabled by default. Before you can run full-text queries, however, you must create a full-text catalog and create a full-text index on the tables or indexed views you want to search.
Set up full-text search in two steps
There are two basic steps to set up a full-text search:
Each full-text index must belong to a full-text catalog. You can create a separate text catalog for each full-text index, or you can associate multiple full-text indexes with a given catalog. A full-text catalog is a virtual object and does not belong to any filegroup. The catalog is a logical concept that refers to a group of full-text indexes.
Get Started with Full-Text Search - SQL Server - Microsoft Docs
In most applications, we need to query or filter text that we have stored in a SQL Server database. If you have a Customer table and you need to filter by name it is ok to write a Select query with a Where clause to compare the input from the user with all customers’ names in that table.
Now, let’s say we have one table, a very simple one, to store all the posts from one blog.
We need to implement a functionality that allows the users to search for posts based on a specified input, but we need to show results even for posts similar to what the user-specified. The user doesn’t know the exact title of the post he is looking for, maybe he is not looking for any specific post but for some information related to what he entered.
Basic searches implementations, like the one we spoke about before to filter customers by name, use queries like these:
SELECT * FROM dbo.Post WHERE Title = 'param';
SELECT * FROM dbo.Post WHERE Title like '%param%';
Let’s say there is a post with the title: “The top 10 phones of 2017” and the user enter something like: “best mobiles” or “best smartphones in 2016”. Will the previous queries give us some good results? No, they won’t. They probably won’t get any result at all.
This kind of search is called Semantic Search and is very complicated to implement, at least from scratch. Fortunately, SQL Server provides a built-in feature that allows us to solve this problem and it is not so hard to get it working.
In order to start using SQL Server Full-Text Search (FTS) capabilities in our database, it’s only required to accomplish two steps:
For our Post table, we want to allow FTS for the Title and Text columns. We need to assign a name to create the catalog.
USE BlogDb
GO
CREATE FULLTEXT CATALOG [PostFTSCatalog] WITH ACCENT_SENSITIVITY = ON
GO
Now we are ready to create the index. It is required that the table contains one unique index (normally we use the primary key). The table can have only one full-text index, to create the full-text index you specify the table, columns involved, the unique index on that table, and a name. This is the statement to create it:
CREATE UNIQUE INDEX UI_Post ON Post(Id);
GO
CREATE FULLTEXT INDEX ON Post
(Title, [Text])
KEY INDEX UI_Post
ON PostFTSCatalog
GO
That’s it, we have enabled SQL Server Full-Text Search in our table.
In order to search we use the built-in functions: contains, freetext, containstable and freetexttable.
Let’s see it in action.
SELECT Title, Text, * FROM [dbo].[Post] where contains(Title, 'phone')
SELECT Title, Text, * FROM [dbo].[Post] where contains(Title, '"ph*"')
SELECT Title, Text, * FROM [dbo].[Post] where contains(*, '"ph*" or "mobile"')
SELECT Title, Text, * FROM [dbo].[Post] where contains(*, '"phone" NEAR "best"')
SELECT Title, Text, * FROM [dbo].[Post] where contains(*, 'FORMSOF(INFLECTIONAL, buy)')
The query on line #1 will return posts where the word “phone” appears on the title. It’s very similar to a like clause but it will perform more efficient than a like. The query #2 will return rows where title contains words that start with “ph”, again very similar to like ‘ph%’.
Line #3 will return records where any of the columns in the full-text search index (in this case Title and Text) contains a word that starts with “ph” or contains the word “mobile”.
Query in line #4 returns records where the Title or Text columns has the word “phone”near the word “best”. Now things are getting better right? Let’s continue.
The last query will get us any row where the Title or Text columns contain the word “buy” in any tense, or in singular or plural in case of a noun. If there is a post that uses the words: buy or bought, it will return them.
SELECT Title, Text, * FROM [dbo].[Post] where freetext(Title, 'phone')
Freetext will match the words with ‘phone’ by it’s meaning, not the exact word. It will also compare the inflectional forms of the words, similar to what the last query of the Contains did. In this case it will return any title that has ‘mobile’, ‘telephone’, ‘smartphone’, etc.
These functions return a table with values of relevance (RANK column) that indicate for each record, how well any word did match with what we are searching for. Freetexttable match by meaning and not only by word.
select p.Title, c.Rank, * from [dbo].[Post] as p inner join
containstable(Post, Title, 'phone') as c
on p.Id = c.[Key]
select p.Title, c.Rank, * from [dbo].[Post] as p inner join
freetexttable(Post, Title, 'best') as c
on p.Id = c.[Key]
This allows us to order by rank, so we get the best results first.
CONTAINSTABLE
Returns a table of zero, one, or more rows for those columns containing character-based data types for precise or fuzzy (less precise) matches to single words and phrases, the proximity of words within a certain distance of one another, or weighted matches. CONTAINSTABLE can be referenced in the FROM clause of a SELECT statement as if it were a regular table name.
Queries using CONTAINSTABLE specify contains-type full-text queries that return a relevance ranking value (RANK) and full-text key (KEY) for each row. The CONTAINSTABLE function uses the same search conditions as the CONTAINS predicate.
For more information see: http://msdn.microsoft.com/en-us/library/ms189760(v=SQL.90).aspx
FREETEXTTABLE
Returns a table of zero, one, or more rows for those columns containing character-based data types for values that match the meaning, but not the exact wording, of the text in the specified freetext_string. FREETEXTTABLE can be referenced in the FROM clause of a SELECT statement like a regular table name.
Queries using FREETEXTTABLE specify free text-type full-text queries that return a relevance ranking value (RANK) and full-text key (KEY) for each row.
For more information see: http://msdn.microsoft.com/en-us/library/ms177652(v=SQL.90).aspx
Full-Text Search With Entity Framework