How to Implement Full-Text Search in SQL Server

Full-text search in SQL Server allows for efficient searching of text data stored in tables. Unlike the traditional LIKE operator, full-text search enables powerful linguistic-based searches, ranking results by relevance and supporting advanced features like inflectional search and proximity queries. In this guide, we will walk through the steps to implement full-text search in SQL Server.

Before using full-text search, ensure that your SQL Server instance supports and has full-text search enabled. You can check this by running:

SELECT SERVERPROPERTY('IsFullTextInstalled') AS FullTextInstalled;

If the result is 1, full-text search is installed; otherwise, you may need to install it.

Step 2: Create a Full-Text Catalog

A full-text catalog is a container for full-text indexes. To create one, use:

CREATE FULLTEXT CATALOG MyFullTextCatalog AS DEFAULT;

Step 3: Create a Full-Text Index

A full-text index is required on the columns you want to search. First, make sure your table has a unique index:

CREATE UNIQUE INDEX UI_MyTable ON MyTable(Id);

Then, create a full-text index:

CREATE FULLTEXT INDEX ON MyTable(
    MyTextColumn LANGUAGE 1033
)
KEY INDEX UI_MyTable
ON MyFullTextCatalog;

The LANGUAGE 1033 specifies English. You can change this according to the language used in your data.

Step 4: Perform Full-Text Searches

Once the index is created, you can perform full-text searches using CONTAINS and FREETEXT.

Using CONTAINS

CONTAINS allows you to search for exact words or phrases:

SELECT * FROM MyTable
WHERE CONTAINS(MyTextColumn, '"search term"');

You can also use logical operators like AND, OR, and NEAR:

SELECT * FROM MyTable
WHERE CONTAINS(MyTextColumn, '"SQL Server" NEAR "Index"');

Using FREETEXT

FREETEXT allows for a broader, natural language search:

SELECT * FROM MyTable
WHERE FREETEXT(MyTextColumn, 'search term');
  • Populate the Full-Text Index: Full-text indexes are updated automatically, but you can manually trigger an update:

    ALTER FULLTEXT INDEX ON MyTable START FULL POPULATION;
    
  • Monitor Full-Text Indexing: Check the status of your full-text population with:

    SELECT * FROM sys.fulltext_indexes;
    
  • Remove a Full-Text Index: If needed, drop the index using:

    DROP FULLTEXT INDEX ON MyTable;
    

Conclusion

Full-text search in SQL Server is a powerful tool for handling complex text-based queries. By enabling full-text search, creating an index, and using CONTAINS or FREETEXT queries, you can significantly improve search performance and relevance in your applications. With proper indexing and management, full-text search can be a game-changer for handling large text-based datasets.

2
131

Related

XML (Extensible Markup Language) is a widely used format for storing and transporting data.

In C#, you can create XML files efficiently using the XmlWriter and XDocument classes. This guide covers both methods with practical examples.

Writing XML Using XmlWriter

XmlWriter provides a fast and memory-efficient way to generate XML files by writing elements sequentially.

Example:

using System;
using System.Xml;

class Program
{
    static void Main()
    {
        using (XmlWriter writer = XmlWriter.Create("person.xml"))
        {
            writer.WriteStartDocument();
            writer.WriteStartElement("Person");

            writer.WriteElementString("FirstName", "John");
            writer.WriteElementString("LastName", "Doe");
            writer.WriteElementString("Age", "30");

            writer.WriteEndElement();
            writer.WriteEndDocument();
        }
        Console.WriteLine("XML file created successfully.");
    }
}

Output (person.xml):

<?xml version="1.0" encoding="utf-8"?>
<Person>
    <FirstName>John</FirstName>
    <LastName>Doe</LastName>
    <Age>30</Age>
</Person>

Writing XML Using XDocument

The XDocument class from LINQ to XML provides a more readable and flexible way to create XML files.

Example:

using System;
using System.Xml.Linq;

class Program
{
    static void Main()
    {
        XDocument doc = new XDocument(
            new XElement("Person",
                new XElement("FirstName", "John"),
                new XElement("LastName", "Doe"),
                new XElement("Age", "30")
            )
        );
        doc.Save("person.xml");
        Console.WriteLine("XML file created successfully.");
    }
}

This approach is ideal for working with complex XML structures and integrating LINQ queries.

When to Use Each Method

  • Use XmlWriter when performance is critical and you need to write XML sequentially.
  • Use XDocument when you need a more readable, maintainable, and flexible way to manipulate XML.

Conclusion

Writing XML files in C# is straightforward with XmlWriter and XDocument. Choose the method that best suits your needs for performance, readability, and maintainability.

2
272

When working with URLs in C#, encoding is essential to ensure that special characters (like spaces, ?, &, and =) don’t break the URL structure. The recommended way to encode a string for a URL is by using Uri.EscapeDataString(), which converts unsafe characters into their percent-encoded equivalents.

string rawText = "hello world!";
string encodedText = Uri.EscapeDataString(rawText);

Console.WriteLine(encodedText); // Output: hello%20world%21

This method encodes spaces as %20, making it ideal for query parameters.

For ASP.NET applications, you can also use HttpUtility.UrlEncode() (from System.Web), which encodes spaces as +:

using System.Web;

string encodedText = HttpUtility.UrlEncode("hello world!");
Console.WriteLine(encodedText); // Output: hello+world%21

For .NET Core and later, Uri.EscapeDataString() is the preferred choice.

28
1193

Removing duplicates from a list in C# is a common task, especially when working with large datasets. C# provides multiple ways to achieve this efficiently, leveraging built-in collections and LINQ.

Using HashSet (Fastest for Unique Elements)

A HashSet<T> automatically removes duplicates since it only stores unique values. This is one of the fastest methods:

List<int> numbers = new List<int> { 1, 2, 2, 3, 4, 4, 5 };
numbers = new HashSet<int>(numbers).ToList();
Console.WriteLine(string.Join(", ", numbers)); // Output: 1, 2, 3, 4, 5

Using LINQ Distinct (Concise and Readable)

LINQ’s Distinct() method provides an elegant way to remove duplicates:

List<int> numbers = new List<int> { 1, 2, 2, 3, 4, 4, 5 };
numbers = numbers.Distinct().ToList();
Console.WriteLine(string.Join(", ", numbers)); // Output: 1, 2, 3, 4, 5

Removing Duplicates by Custom Property (For Complex Objects)

When working with objects, DistinctBy() from .NET 6+ simplifies duplicate removal based on a property:

using System.Linq;
using System.Collections.Generic;

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

List<Person> people = new List<Person>
{
    new Person { Name = "Alice", Age = 30 },
    new Person { Name = "Bob", Age = 25 },
    new Person { Name = "Alice", Age = 30 }
};

people = people.DistinctBy(p => p.Name).ToList();
Console.WriteLine(string.Join(", ", people.Select(p => p.Name))); // Output: Alice, Bob

For earlier .NET versions, use GroupBy():

people = people.GroupBy(p => p.Name).Select(g => g.First()).ToList();

Performance Considerations

  • HashSet<T> is the fastest but only works for simple types.
  • Distinct() is easy to use but slower than HashSet<T> for large lists.
  • DistinctBy() (or GroupBy()) is useful for complex objects but may have performance trade-offs.

Conclusion

Choosing the best approach depends on the data type and use case. HashSet<T> is ideal for primitive types, Distinct() is simple and readable, and DistinctBy() (or GroupBy()) is effective for objects.

1
334