How to Do Full-Text Search in a Mobile App with MongoDB Realm
Rate this tutorial
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:
- Add the
[Indexed(IndexType.FullText)]
attribute on the string property to create an index for searching. - Running queries
- To run Language-Integrated Query (LINQ) queries, use
QueryMethods.FullTextSearch
. For example:realm.All<Book>().Where(b => QueryMethods.FullTextSearch(b.Summary, "fantasy novel")
- To run
Filter
queries, use theTEXT
operator. For example:realm.All<Book>().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<Book>().Where(b => QueryMethods.FullTextSearch(b.Summary, "fantasy novel -rings")
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:
Next, we’ll define a few books with summaries and add those to the realm:
And finally, we are ready for searching the summaries as follows:
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, withName
andSummary
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
wherered
appears in property A andferrari
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!