# How to Do Full-Text Search in a Mobile App with MongoDB Realm

Full-text search is an important feature in modern mobile applications, as it allows you to quickly and efficiently access information within large text datasets. This is fundamental for certain app categories that deal with large amounts of text documents, like news and magazines apps and chat and email applications. 

We are happy to introduce full-text search (FTS) support for Realm — a feature long requested by our developers. While traditional search with string matching returns exact occurrences, FTS returns results that contain the words from the query, but respecting word boundaries. For example, looking for the word “cat” with FTS will return only text containing exactly that word, while a traditional search will return also text containing words like “catalog” and “advocating”. Additionally, it’s also possible to specify words that should *not* be present in the result texts. Another important addition with the Realm-provided FTS is speed: As the index is created beforehand, searches on it are very fast compared to pure string matching.

In this tutorial, we are giving examples using FTS with the .NET SDK, but FTS is also available in the Realm SDK for Kotlin, Dart, and JS, and will soon be available for Swift and Obj-C. 

Later, we will show a practical example, but for now, let us take a look at what you need in order to use the new FTS search with the .NET Realm SDK:

1. Add the `Indexed(IndexType.FullText)]` attribute on the string property to create an index for searching.
2. Running queries
    1. To run Language-Integrated Query (LINQ) queries, use `QueryMethods.FullTextSearch`. For example: `realm.All().Where(b => QueryMethods.FullTextSearch(b.Summary, "fantasy novel")`
    2. To run `Filter` queries, use the `TEXT` operator. For example: `realm.All().Filter("Summary TEXT $0", "fantasy novel");`

Additionally, words in the search phrase can be prepended with a “-” to indicate that certain words should not occur. For example: `realm.All().Where(b => QueryMethods.FullTextSearch(b.Summary, "fantasy novel -rings")`

## Search example

In this example, we will be creating a realm with book summaries indexed and searchable by the full-text search. First, we’ll create the object schema for the books and index on the summary property:

```csharp
public partial class Book : IRealmObject
{
    [PrimaryKey]
    public string Name { get; set; } = null!;

    [Indexed(IndexType.FullText)]
    public string Summary { get; set; } = null!;
}
```

Next, we’ll define a few books with summaries and add those to the realm:

```csharp
// ..
var animalFarm = new Book
{
    Name = "Animal Farm",
    Summary = "Animal Farm is a novel that tells the story of a group of farm animals who rebel against their human farmer, hoping to create a society where the animals can be equal, free, and happy. Ultimately, the rebellion is betrayed, and the farm ends up in a state as bad as it was before."
};

var lordOfTheRings = new Book
{
    Name = "Lord of the Rings",
    Summary = "The Lord of the Rings is an epic high-fantasy novel by English author and scholar J. R. R. Tolkien. Set in Middle-earth, the story began as a sequel to Tolkien's 1937 children's book The Hobbit, but eventually developed into a much larger work."
};

var lordOfTheFlies = new Book
{
    Name = "Lord of the Flies",
    Summary = "Lord of the Flies is a novel that revolves around a group of British boys who are stranded on an uninhabited island and their disastrous attempts to govern themselves."
};

var realm = Realm.GetInstance();

realm.Write(() =>
{
    realm.Add(animalFarm);
    realm.Add(lordOfTheFlies);
    realm.Add(lordOfTheRings);
});
```

And finally, we are ready for searching the summaries as follows:

```csharp
var books = realm.All();

// Returns all books with summaries containing both "novel" and "lord"
var result = books.Where(b => QueryMethods.FullTextSearch(b.Summary, "novel lord"));

// Equivalent query using `Filter`
result = books.Filter("Summary TEXT $0", "novel lord");

// Returns all books with summaries containing both "novel" and "lord", but not "rings"
result = books.Where(b => QueryMethods.FullTextSearch(b.Summary, "novel -rings"));
```

## Additional information 

A few important things to keep in mind when using full-text search:

- Only string properties are valid for an FTS index, also on embedded objects. A collection of strings cannot be indexed. 
- Indexes spanning multiple properties are not supported. For example, if you have a `Book` object, with `Name` and `Summary` properties, you cannot declare a single index that covers both, but you can have one index per property. 
- Doing an FTS lookup for a phrase across multiple properties must be done using a combination of two expressions (i.e., trying to find `red ferrari` where `red` appears in property A and `ferrari` in property B must be done with `(A TEXT 'red') AND (B TEXT 'ferrari'))`.
- FTS only supports languages that use ASCII and Latin-1 character sets (most western languages). Only sequences of (alphanumeric) characters from these sets will be tokenized and indexed. All others will be considered white space.
- Searching is case- and diacritics-insensitive, so “Garcon” matches “garçon”.

We understand there are additional features to FTS we could work to add. Please give us feedback and head over to our [community forums!