Is full text search suitable for searching people's names?
sql-server, sql-server-2008
Solution
It seems that if you want to search multi-part names, full-text search is the easiest and most appropriate approach (please correct me if I'm wrong). The other alternative being `LIKE '%query%'`, however it has too many disadvantages:
- Terrible performance, since it does index scan
- Order of terms matters, e.g. - searching for "John Smith" and "Smith John" will return different results.
- It disregards word boundaries, e.g. - searching for "Ann" will also retrieve "Joanna" and "Danny", which aren't useful matches.
So I went ahead and implemented a full-text search. My queries look something like this:
SELECT * FROM Users WHERE CONTAINS(Name, '"John*"')
The only slight difficulty is that I had to convert user query (John) into a CONTAINS-friendly query ("John*"). To do that, I implemented this method in my UserRepository:
/// <summary>
/// Converts user-entered search query into a query that can be consumed by CONTAINS keyword of SQL Server.
/// </summary>
/// <example>If query is "John S Ju", the result will be "\"John*\" AND \"S*\" AND \"Ju*\"".</example>
/// <param name="query">Query entered by user.</param>
/// <returns>String instance.</returns>
public static string GetContainsQuery(string query)
{
string containsQuery = string.Empty;
var terms = query.Split(new[] { ' ' }, StringSplitOptions.None);
if (terms.Length > 1)
{
for (int i = 0; i < terms.Length; i++)
{
string term = terms[i].Trim();
// Add wildcard term, e.g. - "term*". The reason to add wildcard is because we want
// to allow search by partially entered name parts (partially entered first name and/or
// partially entered last name, etc).
containsQuery += "\"" + term + "*\"";
// If it's not the last term.
if (i < terms.Length - 1)
{
// We want all terms inside user query to match.
containsQuery += " AND ";
}
}
containsQuery = containsQuery.Trim();
}
else
{
containsQuery = "\"" + query + "*\"";
}
return containsQuery;
}
Hope this helps anyone stumbling into the same issue.
PS - I wrote a blogpost documenting this.
Problem
I have a user table with a single column for a person's name: ``` CREATE TABLE [dbo].[Users] ( Id bigint NOT NULL, Name nvarchar(80) NOT NULL, PRIMARY KEY CLUSTERED (Id ASC) ) ``` The `Name` column can contain either a full name or just the first name or anything really (separated by spaces). In order to implement a search on `Name`, I would like to utilize SQL's full-text search, but not sure if it's suitable for searching names/nicknames and not actual words. Also the question is - which language do I choose when creating the FT index on `Name`? Any other considerations? Thank you.