{"id":4446,"date":"2018-01-17T10:30:34","date_gmt":"2018-01-17T18:30:34","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=4446"},"modified":"2025-06-13T20:59:23","modified_gmt":"2025-06-14T03:59:23","slug":"full-text-search-couchbase-mobile-2-0","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/","title":{"rendered":"Introducing Full Text Search (FTS) in Couchbase Mobile 2.0"},"content":{"rendered":"<p>Couchbase Mobile 2.0, introduces powerful Full Text Search (FTS) capabilities on your JSON Documents. This is part of the new Query interface based on <a href=\"https:\/\/www.couchbase.com\/products\/n1ql\/\">N1QL<\/a>, Couchbase\u2019s declarative query language that extends SQL for JSON. If you are familiar with SQL, you will feel right at home with the semantics of the new API.<\/p>\n<p>Full Text Search enables natural lanugage querying. This is the third in a series of posts that discusses the query interface in Couchbase Lite. This blog assumes you are familiar with the fundamentals, so if you haven\u2019t done so already, be sure to review the <a href=\"https:\/\/www.couchbase.com\/blog\/sql-for-json-query-interface-couchbase-mobile\/\">earlier post<\/a> first. If you are interested, links to blogs discussing other features of the Query interface are provided at the end of this post.<\/p>\n<p>You can download the latest pre-release version of Couchbase Mobile 2.0 from <a href=\"https:\/\/www.couchbase.com\/downloads\/\">here<\/a>.<\/p>\n<p><!--more--><\/p>\n<h3 id=\"background\">Background<\/h3>\n<p>If you were using 1.x versions of Couchbase Mobile, you are probably familiar with <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/1.4\/training\/develop\/using-the-database\/index.html#query-documents\">Map-Views<\/a> for creating indexes and queries. In 2.0, you no longer have to create views and map functions! Instead, a simple interface allows you to create indexes and you can use a Query Builder interface to construct your queries. The new query interface is simpler to use and much more powerful in comparison. We will discover some of it\u2019s features in this post.<\/p>\n<h3 id=\"sampleproject\">Sample Project<\/h3>\n<p>While the examples discussed here use Swift for iOS, note that barring some minor differences, the same query interface is supported on the Android and Windows platforms as well.<\/p>\n<p><strong>So with some minor tweaks, you should be able to reuse the query examples in this post when working with other platforms.<\/strong><\/p>\n<p>Follow instructions below if you are interested in a sample Swift Project<\/p>\n<ul>\n<li>Clone the iOS Swift Playground from GitHub\n<pre><code class=\"bash\">$ git clone https:\/\/github.com\/couchbaselabs\/couchbase-lite-ios-api-playground<\/code><\/pre>\n<\/li>\n<li>Follow the installation instructions in the corresponding <a href=\"https:\/\/github.com\/couchbaselabs\/couchbase-lite-ios-api-playground\/blob\/master\/README.md\">README<\/a> file to build and execute the playground.<\/li>\n<\/ul>\n<h3 id=\"sampledatamodel\">Sample Data Model<\/h3>\n<p>We shall use the Travel Sample database located <a href=\"https:\/\/github.com\/couchbaselabs\/couchbase-lite-ios-api-playground\/tree\/master\/travel-sample.cblite2\">here<\/a>. You can embed this pre-built database into your mobile application and start using it for your queries.<\/p>\n<p>The sample data set includes several types of documents as identified by the <code>type<\/code> property in the document. We will focus on documents of <code>type<\/code> <em>\u201clandmark\u201d<\/em> . The JSON document model is shown below. For brevity, we have omitted some of the properties that are not relevant to this post from the model below.<\/p>\n<pre><code class=\"json\"> {\r\n        \"activity\": \"see\",\r\n        \"address\": \"84 rue Claude Monet\",\r\n        \"alt\": \"Fondation Claude Monet\",\r\n        \"city\": \"Giverny\",\r\n        \"content\": \"the house is quietly eccentric and highly interesting in an Orient-influenced style, and includes Monet's collection of [https:\/\/www.intermonet.com\/japan\/ Japanese prints]. There are no original Monet paintings on the site - the real drawcard, is the gardens around the house ...\",\r\n        \"country\": \"France\",\r\n        \"directions\": null,\r\n        \"email\": null,\r\n        \"geo\": {\r\n            \"accuracy\": \"ROOFTOP\",\r\n            \"lat\": 49.0753489,\r\n            \"lon\": 1.5337884\r\n        },\r\n        \"hours\": \"open April-October Mo-Su 9:30-18:00\",\r\n        \"id\": 10061,\r\n        \"image\": null,\r\n        \"name\": \"Monet's House\",\r\n        \"phone\": \"+33 232512821\",\r\n        \"price\": \"\u20ac9, $5 students, \u20ac4 4.00 disabled, under-7s free\",\r\n        \"state\": \"Haute-Normandie\",\r\n        \"title\": \"Giverny\",\r\n        \"tollfree\": null,\r\n        \"type\": \"landmark\",\r\n        \"url\": \"https:\/\/www.fondation-monet.com\/\"\r\n}<\/code><\/pre>\n<p>** Refer to the model above for each of the query examples below. **<\/p>\n<h3 id=\"thedatabasehandle\">The Database Handle<\/h3>\n<p>In the queries below, we will use the <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/2.0\/guides\/couchbase-lite\/native-api\/database\/index.html\"><code>Database<\/code><\/a> API to open\/create CouchbaseLite Database.<\/p>\n<pre><code class=\"swift\">  var options =  DatabaseConfiguration()\r\n  let db = try Database(name: kDBName, config: options)<\/code><\/pre>\n<h3 id=\"thebasics\">The Basics<\/h3>\n<p>Full Text Search enables natural lanugage querying. In our post on the <a href=\"https:\/\/www.couchbase.com\/blog\/sql-for-json-query-interface-couchbase-mobile\/\">Query Fundamentals<\/a>, we discussed the <em>like<\/em> and <em>regex<\/em> expressions for pattern matching operations. FTS supercedes that capability by enabling support for <em>stemming<\/em>, <em>relevance based ranking <\/em>and <em>locale-specific natural language querying<\/em>.<\/p>\n<p>Full Text Searches are <strong>case insensitive<\/strong> and use the <code>match<\/code> query expression. In order to perform FTS, you must create <em>Full Text Index<\/em> on appropriate properties. You can create index on one or more properties.<\/p>\n<h3 id=\"stemming\">Stemming<\/h3>\n<p>Before we proceed with the examples, first a word on Stemming. Stemming is the process of reducing words to their root stem word. So for <a href=\"https:\/\/en.wikipedia.org\/wiki\/Stemming\">instance<\/a>, \u201ccatty\u201d, \u201ccatlike\u201d and \u201ccats\u201d are reduced to the word \u201ccat\u201d. So searching for the term \u201ccats\u201d would give us results that match \u201ccat\u201d, \u201ccatlike\u201d and so on.<\/p>\n<p>Couchbase Lite currently supports Stemming in the following languages<br \/>\n* danish<br \/>\n* dutch<br \/>\n* english<br \/>\n* finnish<br \/>\n* french<br \/>\n* german<br \/>\n* hungarian<br \/>\n* italian<br \/>\n* norwegian<br \/>\n* portuguese<br \/>\n* romanian<br \/>\n* russian<br \/>\n* spanish<br \/>\n* swedish<br \/>\n* turkish<\/p>\n<p>If no specific language is used, the tokenizer will still break the text into words at Unicode whitespace characters. So it should work, although less well, with any language that puts spaces between words.<\/p>\n<h3 id=\"fulltextindex\">Full Text Index<\/h3>\n<p>The <code>name<\/code> that is associated with the index during creation is important. The query examples that we will see later will refer to the appropriate index via the name<\/p>\n<h4 id=\"singlepropertyindex\">Single Property Index<\/h4>\n<p>The following example creates a <code>fullTextIndex<\/code> on the <em>\u201ccontent\u201d<\/em> property of a <code>Document<\/code>. Stemming is enabled by default and the locale is assumed to be the locale of the device. While not shown below, you also have the option of specifying if \u201caccents\u201d have to be ignored or not via the <code>ignoreAccents<\/code> option. By default, accents are not ignored.<\/p>\n<pre class=\"wrap:true lang:swift decode:true \"> let ftsIndex = IndexBuilder.fullTextIndex(items: FullTextIndexItem.property(\"content\"))\r\n try db.createIndex(ftsIndex,withName: \"ContentFTSIndex\")<\/pre>\n<h4 id=\"multiplespropertyindex\">Multiples Property Index<\/h4>\n<p>The following example creates a <code>fullTextIndex<\/code> on <em>\u201ccontent\u201d<\/em> and <em>\u201cname\u201d<\/em> properties of a <code>Document<\/code><\/p>\n<pre class=\"wrap:true lang:swift decode:true \">  let ftsIndex = IndexBuilder.fullTextIndex(items: FullTextIndexItem.property(\"content\"),FullTextIndexItem.property(\"name\"))\r\n  try db.createIndex(ftsIndex,withName: \"ContentAndNameFTSIndex\")<\/pre>\n<h4 id=\"indexwithoutstemming\">Index without stemming<\/h4>\n<p>The following example creates a <code>fullTextIndex<\/code> on the <em>\u201ccontent\u201d<\/em> property of a <code>Document<\/code> with stemming disabled. Stemming is enabled by default using the current device language settings. Setting language to nil will disable stemming.<\/p>\n<pre class=\"wrap:true lang:swift decode:true\">  let ftsIndex = IndexBuilder.fullTextIndex(items: FullTextIndexItem.property(\"content\")).language(nil)\r\n  try db.createIndex(ftsIndex,withName: \"ContentFTSIndexNoStemming\")<\/pre>\n<h3 id=\"ftssearchwithstemming\">FTS Search with Stemming<\/h3>\n<p>The query below fetches the <em>id<\/em> and <em>content<\/em> properties of <em>\u201clandmark\u201d<\/em> <code>type<\/code> documents containing the term <em>\u201cMechanical\u201d<\/em> in the <em>\u201ccontent\u201d<\/em> property. We use the <em>\u201cContentFTSIndex\u201d<\/em> that was created earlier.<\/p>\n<h4 id=\"request\">Request<\/h4>\n<pre class=\"wrap:true lang:swift decode:true \"> let ftsExpression = FullTextExpression.index(\"ContentFTSIndex\")\r\n let searchQuery = QueryBuilder\r\n        .select(SelectResult.expression(Meta.id),\r\n                SelectResult.expression(Expression.property(\"content\")))\r\n        .from(DataSource.database(db))\r\n        .where(\r\nExpression.property(\"type\").equalTo(Expression.string (\"landmark\"))\r\n            .and( ftsExpression.match(\"Mechanical\")))\r\n        .limit(Expression.int(limit))<\/pre>\n<h4 id=\"sampleresponse\">Sample Response<\/h4>\n<p>The response to the above query will include documents that contain the terms \u201cmechanical\u201d, \u201cmechanism\u201d, \u201cmechanisms\u201d, \u201cmechanic\u201d and so on.<\/p>\n<pre><code class=\"json\">[\r\n  {\r\n    \"id\": \"landmark_21703\",\r\n    \"content\": \"The Swiss luxury watch manufacturer, founded in 1851, is known for precise mechanics.\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_2592\",\r\n    \"content\": \"Here you can see the mechanisms that drive San Francisco's famed cable cars, as well as plenty of cable car memorabilia and information on the history of the cable cars.\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_26144\",\r\n    \"content\": \"This scenic section of the Golden Gate National Recreation Area is a favorite for hikers, bikers and beach-goers, with rugged coastal highlands and deep sand dunes. Hang gliding is quite popular here, with several shops for hang gliders in the area. Nearby is the remnants of Battery Davis, a WWII-era military defense mechanism.\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_33234\",\r\n    \"content\": \"Western-style steakhouse features a huge, \u2018country\u2019 bar and even a mechanical bull for those ready for a faux bull-riding adventure. The menu is vast and surprisingly inexpensive. And again, the saloon is a longtime trendy destination along the Sunset Strip for raucous good times.\"\r\n  }\r\n]\r\n<\/code><\/pre>\n<h3 id=\"ftssearchwithoutstemming\">FTS Search <em>without<\/em> Stemming<\/h3>\n<p>The query below fetches the <em>id<\/em> and <em>content<\/em> properties of <em>\u201clandmark\u201d<\/em> <code>type<\/code> documents containing the exact term <em>\u201cMechanical\u201d<\/em> in the <em>\u201ccontent\u201d<\/em> property. We use the <em>\u201cContentFTSIndexNoStemming\u201d<\/em> that was created earlier which specified the option to disable stemming.<\/p>\n<h4 id=\"request\">Request<\/h4>\n<pre class=\"wrap:true lang:swift decode:true \">  let ftsExpression = FullTextExpression.index(\"ContentFTSIndexNoStemming\")\r\n  let searchQuery = QueryBuilder\r\n        .select(SelectResult.expression(Meta.id),\r\n                SelectResult.expression(Expression.property(\"content\")))\r\n        .from(DataSource.database(db))\r\n .where(Expression.property(\"type\").equalTo(Expression.string (\"landmark\"))\r\n            .and( ftsExpression.match(\"Mechanical\")))\r\n        .limit(Expression.int(limit))\r\n<\/pre>\n<h4 id=\"sampleresponse\">Sample Response<\/h4>\n<p>The response to the above query will include documents that contain exactly the term \u201cmechanical\u201d in it. Note again that all searches are case insensitive.<\/p>\n<pre><code class=\"json\">[\r\n  {\r\n    \"id\": \"landmark_33234\",\r\n    \"content\": \"Western-style steakhouse features a huge, \u2018country\u2019 bar and even a mechanical bull for those ready for a faux bull-riding adventure. The menu is vast and surprisingly inexpensive. And again, the saloon is a longtime trendy destination along the Sunset Strip for raucous good times.\"\r\n  }\r\n]\r\n<\/code><\/pre>\n<h3 id=\"ftssearchonmultipleproperties\">FTS Search on Multiple Properties<\/h3>\n<p>The query below fetches the <em>id<\/em> , <em>name<\/em> and <em>content<\/em> properties of <em>\u201clandmark\u201d<\/em> <code>type<\/code> documents containing the term <em>\u201cMechanical\u201d<\/em> in either the <em>\u201cname\u201d<\/em> or the <em>\u201ccontent\u201d<\/em> property. We use the <em>\u201cContentAndNameFTSIndex\u201d<\/em> that was created earlier. This index enabled indexing on the <em>\u201cname\u201d<\/em> and <em>\u201ccontent\u201d<\/em> properties<\/p>\n<h4 id=\"request\">Request<\/h4>\n<pre class=\"wrap:true lang:swift decode:true \"> let ftsExpression = FullTextExpression.index(\"ContentAndNameFTSIndex\")\r\n let searchQuery = QueryBuilder\r\n        .select(SelectResult.expression(Meta.id),\r\n                SelectResult.expression(Expression.property(\"name\")),\r\n                SelectResult.expression(Expression.property(\"content\")))\r\n        .from(DataSource.database(db))\r\n .where(Expression.property(\"type\").equalTo(Expression.string (\"landmark\"))\r\n            .and( ftsExpression.match(\"Mechanical\")))\r\n        .limit(Expression.int(limit))<\/pre>\n<h4 id=\"sampleresponse\">Sample Response<\/h4>\n<p>The response to the above query will include documents that contain the term \u201cmechanical\u201d (or variants of it derived through stemming) in either the \u201cname\u201d or \u201ccontent\u201d property.<\/p>\n<pre><code class=\"json\">[\r\n  {\r\n    \"id\": \"landmark_10062\",\r\n    \"name\": \"Natural Mechanical Museum\",\r\n    \"content\": \"Founded by the Guillemard brothers: Jean-pierre, Ren\u00e9 and G\u00e9rard currently run restorations and exhibitions with the help of an enthusiasts team who devoted their time and known-how to the Patrimony preservation. The museum origin is a private collection of steam internal combustion engines; founded in 1955 by the Guillemard family a GIVERNY residents since generations.\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_21703\",\r\n    \"name\": \"Patek Philippe Salons\",\r\n    \"content\": \"The Swiss luxury watch manufacturer, founded in 1851, is known for precise mechanics.\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_25929\",\r\n    \"name\": \"Cable Car Museum\",\r\n    \"content\": \"Here you can see the mechanisms that drive San Francisco's famed cable cars, as well as plenty of cable car memorabilia and information on the history of the cable cars\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_26144\",\r\n    \"name\": \"Fort Funston\",\r\n    \"content\": \"This scenic section of the Golden Gate National Recreation Area is a favorite for hikers, bikers and beach-goers, with rugged coastal highlands and deep sand dunes. Hang gliding is quite popular here, with several shops for hang gliders in the area. Nearby is the remnants of Battery Davis, a WWII-era military defense mechanism\"\r\n  }\r\n]\r\n<\/code><\/pre>\n<h3 id=\"ftssearchwithlogicalexpressions\">FTS Search with Logical Expressions<\/h3>\n<p>In an earlier example, you saw that by disabling stemming, you can look for the exact search string. But what if you wanted to look for more than one search term ? The <code>match<\/code> query expression accepts logical expressions including AND and OR.<\/p>\n<p>The query below fetches the <em>id<\/em> , and <em>content<\/em> properties of <em>\u201clandmark\u201d<\/em> <code>type<\/code> documents containing the term <em>\u201cMechanical\u201d<\/em> or <em>\u201cMechanism\u201d<\/em> in the <em>\u201ccontent\u201d<\/em> property. We use the <em>\u201cContentFTSIndexNoStemming\u201d<\/em> that was created earlier to disable stemming.<\/p>\n<h4 id=\"request\">Request<\/h4>\n<pre class=\"wrap:true lang:swift decode:true \">let ftsExpression = FullTextExpression.index(\"ContentFTSIndexNoStemming\")\r\nlet searchQuery = QueryBuilder\r\n        .select(SelectResult.expression(Meta.id),\r\n                SelectResult.expression(Expression.property(\"content\")))\r\n        .from(DataSource.database(db))\r\n .where(Expression.property(\"type\").equalTo(Expression.string (\"landmark\"))\r\n            .and( ftsExpression.match(\"Mechanical OR Mechanism\")))\r\n        .limit(Expression.int(limit))<\/pre>\n<h4 id=\"sampleresponse\">Sample Response<\/h4>\n<p>The response to the above query will include documents that contain the eactly the terms \u201cmechanical\u201d or \u201cmechanism\u201d in the \u201ccontent\u201d property.<\/p>\n<pre><code class=\"json\">[\r\n  {\r\n    \"id\": \"landmark_26144\",\r\n    \"content\": \"This scenic section of the Golden Gate National Recreation Area is a favorite for hikers, bikers and beach-goers, with rugged coastal highlands and deep sand dunes. Hang gliding is quite popular here, with several shops for hang gliders in the area. Nearby is the remnants of Battery Davis, a WWII-era military defense mechanism\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_33234\",\r\n    \"content\": \"Western-style steakhouse features a huge, \u2018country\u2019 bar and even a mechanical bull for those ready for a faux bull-riding adventure. The menu is vast and surprisingly inexpensive. And again, the saloon is a longtime trendy destination along the Sunset Strip for raucous good times.\"\r\n  }\r\n]\r\n<\/code><\/pre>\n<h3 id=\"ftssearchwithwilcardexpression\">FTS Search with Wilcard Expression<\/h3>\n<p>You can use the \u201c*\u201d character in the search string to represent zero or more character matches.<\/p>\n<p>The query below fetches the <em>id<\/em> , and <em>content<\/em> properties of <em>\u201clandmark\u201d<\/em> <code>type<\/code> documents containing the term <em>\u201cwalt*\u201d<\/em> in the <em>\u201ccontent\u201d<\/em> property. This will match all search terms that start with \u201cwalt\u201d followed by zero or more characters. We use the <em>\u201cContentFTSIndex\u201d<\/em> that was created earlier.<\/p>\n<p><em>NOTE<\/em>: One could argue that the use of wildcard in the search term could be a naive way of implementing stemming. But then you may end up with derived forms that may not correspond to the terms derived through stemming. So it is preferrable to use stemming if that\u2019s what you need.<\/p>\n<h4 id=\"request\">Request<\/h4>\n<pre class=\"wrap:true lang:swift decode:true \">let ftsExpression = FullTextExpression.index(\"ContentFTSIndex\")\r\nlet searchQuery = QueryBuilder\r\n        .select(SelectResult.expression(Meta.id),\r\n                SelectResult.expression(Expression.property(\"content\")))\r\n        .from(DataSource.database(db))\r\n .where(Expression.property(\"type\").equalTo(Expression.string (\"landmark\"))\r\n        .and( ftsExpression.match(\"walt*\")))\r\n        .limit(Expression.int(limit))<\/pre>\n<h4 id=\"sampleresponse\">Sample Response<\/h4>\n<p>The response to the above query will include documents that contain the terms \u201cwalt\u201d, \u201cWalter\u201d, \u201cWaltham\u201d,\u201cWalthamstow\u201d and so on.<\/p>\n<pre><code class=\"json\">[\r\n  {\r\n    \"id\": \"landmark_10134\",\r\n    \"content\": \"On the Ibrox tour, you get access to the home dressing room and hear a recorded message from Walter Smith and Ally McCoist before climbing the marble staircase, visit the illustrious trophy room, the blue room and the managers office. Tickets, except for matches against Celtic, are available online from the clubs website, ticket centre at the stadium and club outlets at JJB Sports Stores in Glasgow city centre.\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_16104\",\r\n    \"content\": \"Presents the history of Waltham Forest.  The building was constructed to be a work house and has since been used as a police station and a private home.  Its collection includes the Bremer car, built by engineer Frederick Bremer in 1892 it has a claim to being this first petrol-driven car made in Britain.\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_16105\",\r\n    \"content\": \"The ancient nucleus of present day Walthamstow centred around the 12 th century St.Marys Church \"\r\n  },\r\n  {\r\n    \"id\": \"landmark_16574\",\r\n    \"content\": \"Impressive hall architecture complete with tours most days.The Dorothy Chandler Pavilion is open to the public Christmas Eve day with almost round the clock performances by amateur cultural arts groups.The Walt Disney Hall has daily tours ,check website for schedules.\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_8631\",\r\n    \"content \": \"Museum about famous Scottish authors, focussing on Robert Burns, Sir Walter Scott and Robert Louis Stevenson \"\r\n  }\r\n]\r\n<\/code><\/pre>\n<h3 id=\"ftssearchwithstopwords\">FTS Search with Stop Words<\/h3>\n<p>Stop Words refer to common words in a language. In English, this would be terms like \u201cthe\u201d, \u201cis\u201d, \u201cand\u201d , \u201cwhich\u201d and so on.<\/p>\n<h4 id=\"example1:searchstringcontainsstopwords\">Example 1: Search String contains stop words<\/h4>\n<p>Couchbase Lite ignores stop words that appear in search string.<\/p>\n<p>The query below fetches the <em>id<\/em> , and <em>content<\/em> properties of <em>\u201clandmark\u201d<\/em> <code>type<\/code> documents containing the term <em>\u201con the history\u201d<\/em> in the <em>\u201ccontent\u201d<\/em> property. We use the <em>\u201cContentFTSIndex\u201d<\/em> that was created earlier.<\/p>\n<p>Couchbase Lite ignores the stop words \u201con\u201d and \u201cthe\u201d, so you would fetch documents that only include the term \u201chistory\u201d and derived forms of the stem word<\/p>\n<p>Request<\/p>\n<pre class=\"wrap:true lang:swift decode:true\"> let ftsExpression = FullTextExpression.index(\"ContentFTSIndex\")\r\n let searchQuery = QueryBuilder.select(SelectResult.expression(Meta.id),\r\n        SelectResult.expression(Expression.property(\"content\")))\r\n        .from(DataSource.database(db))\r\n .where(Expression.property(\"type\").equalTo(Expression.string (\"landmark\"))\r\n        .and( ftsExpression.match(\"on the history\")))\r\n        .limit(Expression.int(limit))<\/pre>\n<h5 id=\"sampleresponse\">Sample Response<\/h5>\n<p>The response to the above query will include documents that contain the terms \u201chistory\u201d and derived forms of this word such as \u201chistorical\u201d<\/p>\n<pre><code class=\"json\">[\r\n  {\r\n    \"id\": \"landmark_10019\",\r\n    \"content\": \"Museum on military engineering and the history of the British Empire. A quite extensive collection that takes about half a day to see. Of most interest to fans of British and military history or civil engineering.\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_10083\",\r\n    \"content\": \" Tours take about 45 min. In front the building, George Square, the citys notional centre, is populated by several statues of civic leaders and famous figures from history and is often used for outdoor events.\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_10093\",\r\n    \"content\": \"The auditorium has now garnered some world fame for being the place where the Susan Boyle audition - one of the most downloaded YouTube video clips in history - was filmed.\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_10101\",\r\n    \"content\": \"This museum has a large collection of artifacts and exhibits showcasing the history of the city. If you don't want to pay to enter the museum itself, you can just walk into the building (which contains three separate museums) and look at some historical photographs on the walls of the atrium.\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_10105\",\r\n    \"content\": \"The Peoples Palace is a great folk museum, telling the history of Glasgow and its people, from various perspectives, displaying details of Glasgow life (including one of Billy Connolly's banana boots). The Winter Gardens, adjacent, is a pleasant greenhouse with a reasonable cafe.)\"\r\n  }\r\n]\r\n<\/code><\/pre>\n<h4 id=\"example2:ignoringstopwordswhilesearching\">Example 2: Ignoring Stop Words while Searching<\/h4>\n<p>By default, Couchbase Lite ignores stop words within the search content.<\/p>\n<p>The query below fetches the <em>id<\/em> , and <em>content<\/em> properties of <em>\u201clandmark\u201d<\/em> <code>type<\/code> documents containing the terms <em>\u201cblue fin yellow fin\u201d<\/em> in the <em>\u201ccontent\u201d<\/em> property. We use the <em>\u201cContentFTSIndex\u201d<\/em> that was created earlier.<\/p>\n<p>Couchbase Lite ignores stop words during search, so you would fetch documents that include the terms \u201cblue\u201d, \u201cfin\u201d and \u201cyellow\u201d in that order, separated by any number of stop words.<\/p>\n<h5 id=\"request\">Request<\/h5>\n<pre class=\"wrap:true lang:swift decode:true\">let ftsExpression = FullTextExpression.index(\"ContentFTSIndex\")\r\nlet searchQuery = QueryBuilder.select(SelectResult.expression(Meta.id),\r\n       SelectResult.expression(Expression.property(\"content\")))\r\n       .from(DataSource.database(db))\r\n .where(Expression.property(\"type\").equalTo(Expression.string (\"landmark\"))\r\n         .and( ftsExpression.match(\"blue fin yellow fin\")))\r\n        .limit(Expression.int(limit))<code class=\"swift\"><\/code><\/pre>\n<h5 id=\"sampleresponse\">Sample Response<\/h5>\n<p>The response to the above query will include documents that contain the terms \u201cblue\u201d, \u201cfin\u201d and \u201cyellow\u201d separated by any number of stop words such as \u201cblue fin and yellow fin\u201d<\/p>\n<pre><code class=\"json\">[\r\n  {\r\n    \"id\": \"landmark_18840\",\r\n    \"content\": \"This large aquarium specializes in exhibiting local sea life in typical local habitat displays, and has many spectacular exhibits. It is particularly known for its Kelp Forest exhibit, three stories high, filled with several varieties of giant kelp and a wide variety of marine animal species, and also for its million-gallon Open Sea exhibit with large blue fin and yellow fin tunas, mahi-mahis, sharks (including an occasional Great White Shark as a very temporary visitor, before being released back to the ocean), ocean sunfish (mola-molas) and sea turtles. The best exhibits include a large tank of silver sardines that swim around and around above one's head, and one of rescued sea otters deemed unreturnable to the wild and therefore kept at the aquarium.  )\"\r\n  }\r\n]\r\n<\/code><\/pre>\n<h3 id=\"ftssearchwithranking\">FTS Search with Ranking<\/h3>\n<p>You can use the <code>FullTextFunction.rank<\/code> to specify the rank order of the search results. This is useful to rate the matches in order of best match.<\/p>\n<p>The query below fetches the <em>id<\/em> , and <em>content<\/em> properties of <em>\u201clandmark\u201d<\/em> <code>type<\/code> documents containing the term <em>\u201cattract\u201d<\/em> in the <em>\u201ccontent\u201d<\/em> property. The documents are ordered in descending order according to rank which means that the document which the maximum number of matches is sorted higher than the rest.<\/p>\n<h5 id=\"request\">Request<\/h5>\n<pre class=\"wrap:true lang:swift decode:true \">let ftsExpression = FullTextExpression.index(\"ContentFTSIndexNoStemming\")\r\nlet searchQuery = QueryBuilder.select(SelectResult.expression(Meta.id),\r\n     SelectResult.expression(Expression.property(\"content\")))\r\n        .from(DataSource.database(db))\r\n .where(Expression.property(\"type\").equalTo(Expression.string (\"landmark\"))\r\n        .and( ftsExpression.match(\"attract\")))\r\n        .orderBy(Ordering.expression(FullTextFunction.rank(\"ContentFTSIndexNoStemming\")).descending())\r\n        .limit(Expression.int(limit))<\/pre>\n<h5 id=\"sampleresponse\">Sample Response<\/h5>\n<p>The response to the above query will include documents that include the term <em>\u201cattract\u201d<\/em> or derived versions of it. Documents with the maximum number of matches are sorted higher.<\/p>\n<pre><code class=\"json\">[\r\n  {\r\n    \"id\": \"landmark_22056\",\r\n    \"content\": \"Top paid-for visitor attraction in Wales including a farm, indoor vintage funfair, zoo and indoor and outdoor adventure play. All-weather family attraction with 50% of attractions undercover.\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_16309\",\r\n    \"content\": \"The London Bridge Experience and London Tombs are two scare attractions for one price and have been voted the UK's Best Year Round Scare Attraction for three years running.\"\r\n  },\r\n  {\r\n    \"id\": \"landmark_25216\",\r\n    \"content\": \"TA seaside amusement park located near the southern end of Mission Beach, Belmont Park is a landmark with a number of shops, restaurants, an arcade, and a bunch of rides. The big attraction is the Giant Dipper, a historic roller coaster that is one of the only two remaining oceanfront roller coasters still operating on the west coast. Among the other rides is a FlowRider (a simulated wave attraction which you can bodyboard on), an antique carousel, bumper cars, slides, pendulum rides, tilt-a-whirl, and a trampoline \"\r\n  },\r\n  {\r\n    \"id\": \"landmark_1059\",\r\n    \"content\": \"Aims to tell the history of flight throughout the 20th Century, and has a large collection of aircraft, including British Airways Concorde G-BOAA.  Another rather good attraction (and well worth the look) is the De-Havilland Comet 4C, a derivative of the Worlds first jetliner.\"\r\n  }\r\n]\r\n<\/code><\/pre>\n<h3 id=\"limitations\">Limitations<\/h3>\n<p>While the FTS capabily in Couchbase Lite 2.0 is extremely powerful and would suffice for use cases typical on an embedded database, there are a few limitations<\/p>\n<ul>\n<li>Match Expression can only be at the top-level or top-level AND expression.\u00a0This means that the following expression is not allowed\u00a0<span style=\"color: #222222;font-family: Monaco, Consolas, 'Andale Mono', 'DejaVu Sans Mono', monospace;font-size: 15px;background-color: #e9ebec\">ftsExpression.match(&#8220;attract&#8221;).or(ftsExpression2.match(&#8220;museum&#8221;))<\/span><\/li>\n<\/ul>\n<ul>\n<li>Custom Language Tokenizers<br \/>\nThe list of supported languages was specified earlier. At the time of writing this post, you cannot plug in a custom tokenizer in order to extend support to other languages<\/li>\n<li>\u00a0Fuzzy Search Support<br \/>\nWe cannot specify a \u201cfuzziness\u201d factor on the query that may result in less relevant matches being considered<\/li>\n<li>\u00a0Facets<br \/>\nThere is no support for faceted search<\/li>\n<\/ul>\n<p>Bear in mind that Couchbase Lite is an embedded database. So one could argue that the FTS capabilities does not have to be as extensive as a server side database implementation. The support for these will be evaluated in future releases.<\/p>\n<h3 id=\"whatnext\">What Next<\/h3>\n<p>This blog post looked at how you can leverage the Full Text Search (FTS) capabilities in the new Query API in Couchbase Mobile 2.0. This is a start. Expect to see more functionality in future releases. You can download the latest release from our <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/2.0\/whatsnew.html\">downloads<\/a> page.<\/p>\n<p>Here are a few other Couchbase Mobile Query related posts that may be of interest<br \/>\n&#8211; This <a href=\"https:\/\/www.couchbase.com\/blog\/sql-for-json-query-interface-couchbase-mobile\/\">blog post<\/a> discusses the fundamentals<br \/>\n&#8211; This <a href=\"https:\/\/www.couchbase.com\/blog\/querying-array-collections-couchbase-mobile\/\">blog post<\/a> discusses how to query array collections<br \/>\n&#8211; This <a href=\"https:\/\/www.couchbase.com\/blog\/join-queries-couchbase-mobile\/\">blog post<\/a> discusses how to do JOIN queries<\/p>\n<p>If\u00a0you have questions or feedback, please leave a comment below or feel free to reach out to me at Twitter\u00a0<a href=\"https:\/\/twitter.com\/rajagp\">@rajagp<\/a>\u00a0or email me\u00a0<a href=\"mailto:priya.rajagopal@couchbase.com\">priya.rajagopal@couchbase.com<\/a>. \u00a0The\u00a0<a href=\"https:\/\/www.couchbase.com\/forums\/\">Couchbase Forums<\/a> are another good place to reach out with\u00a0questions.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Couchbase Mobile 2.0, introduces powerful Full Text Search (FTS) capabilities on your JSON Documents. This is part of the new Query interface based on N1QL, Couchbase\u2019s declarative query language that extends SQL for JSON. If you are familiar with SQL, [&hellip;]<\/p>\n","protected":false},"author":1423,"featured_media":4447,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1815,7667,1810,2165,1812],"tags":[1261],"ppma_author":[8948],"class_list":["post-4446","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-couchbase-lite","category-couchbase-mobile","category-full-text-search","category-n1ql-query","tag-json"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.8 (Yoast SEO v25.8) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Introducing Full Text Search (FTS) in Couchbase Mobile 2.0<\/title>\n<meta name=\"description\" content=\"Couchbase Mobile 2.0 brings us powerful Full text Search (FTS) capabilities of your JSON Documents. This post walks you through several use cases.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Introducing Full Text Search (FTS) in Couchbase Mobile 2.0\" \/>\n<meta property=\"og:description\" content=\"Couchbase Mobile 2.0 brings us powerful Full text Search (FTS) capabilities of your JSON Documents. This post walks you through several use cases.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-01-17T18:30:34+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T03:59:23+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/01\/fts.png\" \/>\n\t<meta property=\"og:image:width\" content=\"430\" \/>\n\t<meta property=\"og:image:height\" content=\"522\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Priya Rajagopal, Senior Director, Product Management\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@rajagp\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Priya Rajagopal, Senior Director, Product Management\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/\"},\"author\":{\"name\":\"Priya Rajagopal, Senior Director, Product Management\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c2da90e57717ee4970c48a87a131ac2c\"},\"headline\":\"Introducing Full Text Search (FTS) in Couchbase Mobile 2.0\",\"datePublished\":\"2018-01-17T18:30:34+00:00\",\"dateModified\":\"2025-06-14T03:59:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/\"},\"wordCount\":1832,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/01\/fts.png\",\"keywords\":[\"JSON\"],\"articleSection\":[\"Best Practices and Tutorials\",\"Couchbase Lite\",\"Couchbase Mobile\",\"Full-Text Search\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/\",\"name\":\"Introducing Full Text Search (FTS) in Couchbase Mobile 2.0\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/01\/fts.png\",\"datePublished\":\"2018-01-17T18:30:34+00:00\",\"dateModified\":\"2025-06-14T03:59:23+00:00\",\"description\":\"Couchbase Mobile 2.0 brings us powerful Full text Search (FTS) capabilities of your JSON Documents. This post walks you through several use cases.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/01\/fts.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/01\/fts.png\",\"width\":430,\"height\":522,\"caption\":\"Full Text Search\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Introducing Full Text Search (FTS) in Couchbase Mobile 2.0\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c2da90e57717ee4970c48a87a131ac2c\",\"name\":\"Priya Rajagopal, Senior Director, Product Management\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4b50a54778b979d8c345b036ab138734\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/acfb2349788955262cd069497a9e7bdb0e97c26326f2e55811e7c1174e9ef1be?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/acfb2349788955262cd069497a9e7bdb0e97c26326f2e55811e7c1174e9ef1be?s=96&d=mm&r=g\",\"caption\":\"Priya Rajagopal, Senior Director, Product Management\"},\"description\":\"Priya Rajagopal is a Senior Director of Product Management at Couchbase responsible for developer platforms for the cloud and the edge. She has been professionally developing software for over 20 years in several technical and product leadership positions, with 10+ years focused on mobile technologies. As a TISPAN IPTV standards delegate, she was a key contributor to the IPTV standards specifications. She has 22 patents in the areas of networking and platform security.\",\"sameAs\":[\"https:\/\/x.com\/rajagp\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/priya-rajagopalcouchbase-com\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Introducing Full Text Search (FTS) in Couchbase Mobile 2.0","description":"Couchbase Mobile 2.0 brings us powerful Full text Search (FTS) capabilities of your JSON Documents. This post walks you through several use cases.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/","og_locale":"en_US","og_type":"article","og_title":"Introducing Full Text Search (FTS) in Couchbase Mobile 2.0","og_description":"Couchbase Mobile 2.0 brings us powerful Full text Search (FTS) capabilities of your JSON Documents. This post walks you through several use cases.","og_url":"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/","og_site_name":"The Couchbase Blog","article_published_time":"2018-01-17T18:30:34+00:00","article_modified_time":"2025-06-14T03:59:23+00:00","og_image":[{"width":430,"height":522,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/01\/fts.png","type":"image\/png"}],"author":"Priya Rajagopal, Senior Director, Product Management","twitter_card":"summary_large_image","twitter_creator":"@rajagp","twitter_misc":{"Written by":"Priya Rajagopal, Senior Director, Product Management","Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/"},"author":{"name":"Priya Rajagopal, Senior Director, Product Management","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c2da90e57717ee4970c48a87a131ac2c"},"headline":"Introducing Full Text Search (FTS) in Couchbase Mobile 2.0","datePublished":"2018-01-17T18:30:34+00:00","dateModified":"2025-06-14T03:59:23+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/"},"wordCount":1832,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/01\/fts.png","keywords":["JSON"],"articleSection":["Best Practices and Tutorials","Couchbase Lite","Couchbase Mobile","Full-Text Search","SQL++ \/ N1QL Query"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/","url":"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/","name":"Introducing Full Text Search (FTS) in Couchbase Mobile 2.0","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/01\/fts.png","datePublished":"2018-01-17T18:30:34+00:00","dateModified":"2025-06-14T03:59:23+00:00","description":"Couchbase Mobile 2.0 brings us powerful Full text Search (FTS) capabilities of your JSON Documents. This post walks you through several use cases.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/01\/fts.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/01\/fts.png","width":430,"height":522,"caption":"Full Text Search"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/full-text-search-couchbase-mobile-2-0\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Introducing Full Text Search (FTS) in Couchbase Mobile 2.0"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c2da90e57717ee4970c48a87a131ac2c","name":"Priya Rajagopal, Senior Director, Product Management","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4b50a54778b979d8c345b036ab138734","url":"https:\/\/secure.gravatar.com\/avatar\/acfb2349788955262cd069497a9e7bdb0e97c26326f2e55811e7c1174e9ef1be?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/acfb2349788955262cd069497a9e7bdb0e97c26326f2e55811e7c1174e9ef1be?s=96&d=mm&r=g","caption":"Priya Rajagopal, Senior Director, Product Management"},"description":"Priya Rajagopal is a Senior Director of Product Management at Couchbase responsible for developer platforms for the cloud and the edge. She has been professionally developing software for over 20 years in several technical and product leadership positions, with 10+ years focused on mobile technologies. As a TISPAN IPTV standards delegate, she was a key contributor to the IPTV standards specifications. She has 22 patents in the areas of networking and platform security.","sameAs":["https:\/\/x.com\/rajagp"],"url":"https:\/\/www.couchbase.com\/blog\/author\/priya-rajagopalcouchbase-com\/"}]}},"authors":[{"term_id":8948,"user_id":1423,"is_guest":0,"slug":"priya-rajagopalcouchbase-com","display_name":"Priya Rajagopal, Senior Director, Product Management","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/acfb2349788955262cd069497a9e7bdb0e97c26326f2e55811e7c1174e9ef1be?s=96&d=mm&r=g","author_category":"","last_name":"Rajagopal, Senior Director, Product Management","first_name":"Priya","job_title":"","user_url":"","description":"Priya Rajagopal is a Senior Director of Product Management at Couchbase responsible for developer platforms for the cloud and the edge. She has been professionally developing software for over 20 years in several technical and product leadership positions, with 10+ years focused on mobile technologies. As a TISPAN IPTV standards delegate, she was a key contributor to the IPTV standards specifications. She has 22 patents in the areas of networking and platform security."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/4446","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/1423"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=4446"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/4446\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/4447"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=4446"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=4446"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=4446"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=4446"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}