{"id":2149,"date":"2016-02-24T17:06:22","date_gmt":"2016-02-24T17:06:22","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2149"},"modified":"2025-06-13T20:59:48","modified_gmt":"2025-06-14T03:59:48","slug":"cbftjavapreview","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/cbftjavapreview\/","title":{"rendered":"Visualiza\u00e7\u00e3o da pesquisa de texto completo no Couchbase usando o Java SDK"},"content":{"rendered":"<p>In this blog post, we&#8217;ll have a look at the preview API for full text search in <a href=\"https:\/\/www.couchbase.com\/next\/\"><strong>Couchbase 4.5<\/strong><\/a>. Please note that this API, released in the latest <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/4.1\/sdks\/java-2.2\/download-links.html\">Java SDK <\/a>\u00a0(<code>2.2.4<\/code>), is still <code>@Experimental<\/code>.<\/p>\n<p>We&#8217;ll cover:<\/p>\n<ul class=\"toc\">\n<li><a href=\"#toc_0\">Full Text Search in Couchbase?<\/a><\/li>\n<li><a href=\"#toc_1\">The Java API<\/a><\/li>\n<li><a href=\"#toc_2\">Various Types of Queries<\/a>\n<ul>\n<li><a href=\"#toc_3\">Fuzzy Querying<\/a><\/li>\n<li><a href=\"#toc_4\">Multiple Terms: MatchPhrase<\/a><\/li>\n<li><a href=\"#toc_5\">Regexp Query<\/a><\/li>\n<li><a href=\"#toc_6\">Prefix Query<\/a><\/li>\n<li><a href=\"#toc_7\">Range and Date Queries<\/a><\/li>\n<li><a href=\"#toc_8\">Generic Querying<\/a><\/li>\n<li><a href=\"#toc_9\">Combining<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#toc_10\">Getting Hit Explanations<\/a><\/li>\n<li><a href=\"#toc_11\">Conclusion<\/a><\/li>\n<\/ul>\n<p>This experimental API can be used with Couchbase Server 4.5 Developer Preview, provided you use the <code>2.2.4<\/code>\u00a0Java SDK client, which you can get through Maven.\u00a0Add the following dependency to your <code>pom.xml<\/code>:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-markup\">\r\n    com.couchbase.client\r\n    java-client\r\n    2.2.4\r\n<\/code><\/pre>\n<\/div>\n<div><\/div>\n<h2 id=\"toc_0\">Full Text Search in Couchbase?<\/h2>\n<p>Yes! The upcoming <code>4.5<\/code> server release, (codename Watson) will include a full text indexer (FTS, also known as CBFT) based on the open-source <a href=\"https:\/\/www.blevesearch.com\/\">Bleve<\/a> project. Bleve is all about full-text search and indexing in Go (shoutout to our very own <a href=\"https:\/\/twitter.com\/mschoch\">Marty Schoch<\/a> for initiating this project).<\/p>\n<p>The idea is to leverage Bleve to provide an off-the-shelf full text search in Couchbase Server, without having to use connectors to external software (that runs on their own cluster). If that off-the-shelf solution doesn&#8217;t meet your needs all the way of course you still can use these <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/4.0\/connectors\/elasticsearch-2.1\/elastic-intro.html\">connectors<\/a>, but for simpler needs you are good to go with a single solution.<\/p>\n<p>FTS offers a host of capabilities that are provided by Bleve: Text Analyzers, Tokenizers and post-processing Token Filters that are beyond the scope of this post, as well as the numerous types of <em>queries<\/em> that you can run on the resulting indexes. Let&#8217;s see what those types are and how you can expect to use them in the context of the Java SDK.<\/p>\n<p>In the rest of this blog post, we&#8217;ll use 3 indexes that you will be able to build through the web administrative console in the upcoming 4.5 Developer Preview:<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2016\/february\/cbftjavapreview\/pathtocbft.png\" align=\"middle\" \/><\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2016\/february\/cbftjavapreview\/createcbftindex.png\" align=\"middle\" \/><\/p>\n<p>Here is the list of indexes in the UI:<br \/>\n<img decoding=\"async\" src=\"\/wp-content\/original-assets\/2016\/february\/cbftjavapreview\/indexlist.png\" align=\"middle\" \/><br \/>\nWe have:<\/p>\n<ul>\n<li>a <code>beerIndex<\/code> that indexes the whole content of each document in the <code>`beer-sample`<\/code> bucket.<\/li>\n<li>a <code>travelIndex<\/code> that indexes the whole content of each document in the <code>`travel-sample`<\/code> bucket.<\/li>\n<li>an alias index, <code>commonIndex<\/code>, that is an union of the two indexes above.<\/li>\n<\/ul>\n<h2 id=\"toc_1\">The Java API<\/h2>\n<p>The entry point of the full text search feature in the Java SDK is on the <code>Bucket<\/code>, using the <code>query(SearchQuery ftq)<\/code> method. This is consistent with the existing querying methods already present in the API to run a <code>ViewQuery<\/code> or a <code>N1qlQuery<\/code>.<\/p>\n<p>The API for full text search follows the <em>builder<\/em> pattern. Identify the type of query you want and use the corresponding builder to construct it, get the <code>SearchQuery<\/code> out of it using <code>build()<\/code> and execute it using <code>bucket.query(searchQuery)<\/code>.<\/p>\n<p>Let&#8217;s take a (very simple) example and see how it can be consumed:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-java\">\/\/we'll use that Cluster and Bucket for the remainder of the examples\r\nCluster cluster = CouchbaseCluster.create(\"127.0.0.1\");\r\nBucket bucket = cluster.openBucket(\"beer-sample\");\r\n\r\n\/\/we use a simple form of query:\r\nSearchQuery ftq = MatchQuery.on(\"beerIndex\").match(\"national\").limit(3).build();\r\n\r\n\/\/we fire the query and look at results\r\nSearchQueryResult result = bucket.query(ftq);\r\nSystem.out.println(\"totalHits: \" + result.totalHits());\r\nfor (SearchQueryRow row : result) {\r\n    System.out.println(row);\r\n}<\/code><\/pre>\n<\/div>\n<p>If we look at each section individually, here&#8217;s what happened:<\/p>\n<ol>\n<li>We create a simple <code>MatchQuery<\/code> on a single term.<\/li>\n<li>It runs on the beer sample (<code>.on(beerIndex<\/code>), looks for textual occurrences of the word &#8220;national&#8221; (<code>.query(\"national\")<\/code>) or close terms.<\/li>\n<li>Additional configuration is done to limit the number of results to 3 (<code>limit(3)<\/code>) and the actual query is created at this point (<code>.build()<\/code>).<\/li>\n<li>The query is executed (<code>bucket.query(ftq)<\/code>) and returns a <code>SearchQueryResult<\/code>.<\/li>\n<li>We output the result&#8217;s <code>totalHits()<\/code> and individual rows (also accessible as a list through <code>hits()<\/code>).<\/li>\n<\/ol>\n<p>Running that code outputs:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-none\">totalHits: 31\r\nSearchQueryHit{id='dc_brau', score=0.09068310490562362, fragments={}}\r\nSearchQueryHit{id='brouwerij_nacional_balashi', score=0.12085760187148556, fragments={}}\r\nSearchQueryHit{id='cervecera_nacional', score=0.09863195902067363, fragments={}}<\/code><\/pre>\n<\/div>\n<p>We see that total hits gives us the actual number of hits before the limit was applied. The <code>hits()<\/code> method returns 3 <code>SearchQueryRow<\/code> objects, as requested.<\/p>\n<p>Each hit contains the key to the associated document in Couchbase (<code>id()<\/code>), as well as more information on the matching, eg. a score for the match (<code>score()<\/code>)&#8230; If you want, you can retrieve the associated document using <code>bucket.get(row.id())<\/code>:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-java\">result = bucket.query(ftq);\r\nSystem.out.println(\"totalHits: \" + result.totalHits());\r\nfor (SearchQueryRow row : result) {\r\n    System.out.println(row);\r\n    System.out.println(bucket.get(row.id()).content());\r\n}<\/code><\/pre>\n<\/div>\n<p>This gives us, for the first hit:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-none\">SearchQueryHit{id='dc_brau', score=0.09068310490562362, fragments={}}\r\n{\"country\":\"United States\",\"website\":\"https:\/\/www.dcbrau.com\/\",\"code\":\"20018\",\"address\":[\"3178-B Bladensburg Rd. NE\"],\"city\":\"Washington\",\"phone\":\"\",\"name\":\"DC Brau\",\r\n\"description\":\"The first brewery to open in the nation's capital since Prohibition.\",\"state\":\"DC\",\"type\":\"brewery\",\"updated\":\"2011-08-08 19:02:40\"}<\/code><\/pre>\n<\/div>\n<p>If we look closely at the document&#8217;s JSON, we notice where the document probably matched. In the &#8220;<code>description<\/code>&#8221; field of the document, there is this sentence:<\/p>\n<blockquote><p>The first brewery to open in the <strong>nation<\/strong>&#8216;s capital since Prohibition.<\/p><\/blockquote>\n<p>Also notice that the text query looked for the word requested and derived words that have the same root. It actually applied a fuzziness of 2 (see the next section).<\/p>\n<p>This pattern can be applied to the other types of queries as well, so let&#8217;s have a look at a few more, see what kind of search can be performed.<\/p>\n<h2 id=\"toc_2\">Various Types of Queries<\/h2>\n<h2 id=\"toc_3\">Fuzzy Querying<\/h2>\n<p>Fuzzy querying can be performed with the <code>MatchQuery<\/code>, specifying a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Levenshtein_distance\">Levenshtein distance<\/a> as the maximum <code>fuzziness()<\/code> to allow on the term:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-java\">result = bucket.query(MatchQuery.on(\"beerIndex\")\r\n    .match(\"sammar\")\r\n    .field(\"name\")\r\n    .fuzziness(2) \/\/actually the default\r\n    .build());\r\n\r\nSystem.out.println(\"nFuzzy Match Query\");\r\nSystem.out.println(\"totalHits (fuzziness = 2): \" + result.totalHits());\r\nfor (SearchQueryRow row : result) {\r\n    System.out.println(bucket.get(row.id()).content().get(\"name\"));\r\n}<\/code><\/pre>\n<\/div>\n<p>At a fuzziness of <strong>2<\/strong>, this matches words like &#8220;hammer&#8221;, &#8220;mamma&#8221; or &#8220;summer&#8221;:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-none\">Fuzzy Match Query\r\ntotalHits (fuzziness = 2): 45\r\nMamma Mia! Pizza Beer\r\nRedhook Long Hammer IPA\r\nSummer Wheat<\/code><\/pre>\n<\/div>\n<p>At a fuzziness of <strong>1<\/strong>, no match is found:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-none\">Fuzzy Match Query\r\ntotalHits (fuzziness = 1): 0<\/code><\/pre>\n<\/div>\n<p>A type of query dedicated to fuzziness and not applying any analyzer is also provided in the <code>FuzzyQuery<\/code>.<\/p>\n<h2 id=\"toc_4\">Multiple Terms: MatchPhrase<\/h2>\n<p>As we saw, <code>MatchQuery<\/code> is a term-based query that allows to optionally specify fuzziness and also applies the same filter to the searched term that may have been applied to the field (eg. stemming, etc&#8230;):<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-java\">MatchQuery.on(\"beerIndex\")\r\n    .match(\"sesonal\")\r\n    .fuzziness(2)\r\n    .field(\"description\").build();<\/code><\/pre>\n<\/div>\n<p>You can search for multiple terms in a single query by using a <code>Match Phrase<\/code> query. Terms are analyzed and fuzziness can be optionally activated:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-java\">MatchPhraseQuery.on(\"beerIndex\").matchPhrase(\"summer seasonal\").field(\"description\");<\/code><\/pre>\n<\/div>\n<h2 id=\"toc_5\">Regexp Query<\/h2>\n<p>A <code>RegexpQuery<\/code> doesn&#8217;t only do literal matching but allows to match using a regular expression. Take this example:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-java\">result = bucket.query(RegexpQuery.on(\"beerIndex\")\r\n    .regexp(\"[tp]ale\")\r\n    .field(\"name\")\r\n    .build());\r\n\r\nSystem.out.println(\"nRegexp Query\");\r\nSystem.out.println(\"totalHits: \" + result.totalHits());\r\nfor (SearchQueryRow row : result) {\r\n    System.out.println(bucket.get(row.id()).content().get(\"name\"));\r\n}<\/code><\/pre>\n<\/div>\n<p>Notice this query targets a particular field in the json (<code>field(\"name\")<\/code>). We want all names that contain either &#8220;tale&#8221; or &#8220;pale&#8221;. Here are a few names that match this query:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-none\">Regexp Query\r\ntotalHits: 408\r\nTall Tale Pale Ale\r\nBard's Tale Beer Company\r\nPale Ale<\/code><\/pre>\n<\/div>\n<h2 id=\"toc_6\">Prefix Query<\/h2>\n<p>A <code>PrefixQuery<\/code> looks for word occurrences that start with the given string:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-java\">result = bucket.query(PrefixQuery.on(\"beerIndex\")\r\n    .prefix(\"weiss\")\r\n    .field(\"name\")\r\n    .build());\r\n\r\nSystem.out.println(\"nPrefix Query\");\r\nSystem.out.println(\"totalHits: \" + result.totalHits());\r\nfor (SearchQueryRow row : result) {\r\n    System.out.println(bucket.get(row.id()).content().get(\"name\"));\r\n}<\/code><\/pre>\n<\/div>\n<p>Once again we only look inside the <code>name<\/code> field, this time for words that start with &#8220;weiss&#8221;:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-none\">Prefix Query\r\ntotalHits: 74\r\nBavarian-Weissbier Hefeweisse \/ Weisser Hirsch\r\nM\u00fcnchner Kindl Weissbier \/ M\u00fcnchner Weisse\r\nFranziskaner Hefe-Weissbier Hell  \/ Franziskaner Club-Weiss\r\nWeissenheimer Wheat<\/code><\/pre>\n<\/div>\n<h2 id=\"toc_7\">Range and Date Queries<\/h2>\n<p><code>FTS<\/code> is also good with non-textual data. For instance, the <code>NumericRangeQuery<\/code> allows you to look for numerical values within a provided range:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-java\">result = bucket.query(NumericRangeQuery.on(\"beerIndex\")\r\n    .min(3)\r\n    .max(4)\r\n    .field(\"abv\")\r\n    .fields(\"name\", \"abv\")\r\n    .build());\r\n\r\nSystem.out.println(\"nNumeric Range Query\");\r\nSystem.out.println(\"totalHits: \" + result.totalHits());\r\nfor (SearchQueryRow row : result) {\r\n    JsonDocument doc = bucket.get(row.id());\r\n    System.out.println(\"\"\" + doc.content().get(\"name\") + \"\", abv: \" + doc.content().get(\"abv\"));\r\n}<\/code><\/pre>\n<\/div>\n<p>Which outputs:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-none\">Numeric Range Query\r\ntotalHits: 62\r\n\"Stud Service Stout\", abv: 3.1\r\n\"Blonde\", abv: 3.0\r\n\"Locke Mountain Light\", abv: 3.7<\/code><\/pre>\n<\/div>\n<p>Dates are covered as well with the <code>DateRangeQuery<\/code>:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-java\">Calendar calendar = Calendar.getInstance();\r\ncalendar.set(2011, Calendar.MARCH, 1);\r\nDate start = calendar.getTime();\r\ncalendar.set(2011, Calendar.APRIL, 1);\r\nDate end = calendar.getTime();\r\n\r\nresult = bucket.query(DateRangeQuery.on(\"beerIndex\")\r\n    .start(start)\r\n    .end(end)\r\n    .field(\"updated\")\r\n    .fields(\"name\", \"updated\")\r\n    .build());\r\n\r\nSystem.out.println(\"nDate Range Query\");\r\nSystem.out.println(\"totalHits: \" + result.totalHits());\r\nfor (SearchQueryRow row : result) {\r\n    JsonDocument doc = bucket.get(row.id());\r\n    System.out.println(\"\"\" + doc.content().get(\"name\") + \"\", updated: \" + doc.content().get(\"updated\"));\r\n}    <\/code><\/pre>\n<\/div>\n<p>Which outputs:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-none\">Date Range Query\r\ntotalHits: 4\r\n\"Dank\", updated: 2011-03-16 09:06:54\r\n\"Oso\", updated: 2011-03-16 09:05:15\r\n\"Summer Teeth\", updated: 2011-03-08 12:22:14\r\n\"Columbus Brewing Company\", updated: 2011-03-08 12:19:07<\/code><\/pre>\n<\/div>\n<h2 id=\"toc_8\">Generic Querying<\/h2>\n<p><code>FTS<\/code> also offer a more generic form of querying that combines phrases, terms and more using the <a href=\"https:\/\/www.blevesearch.com\/docs\/Query-String-Query\/\"><code>String Query syntax<\/code><\/a>. This is accessible in the API through the <code>StringQuery<\/code>.<\/p>\n<h2 id=\"toc_9\">Combining<\/h2>\n<p>Additionally, you can combine simple criteria like <code>MatchQuery<\/code> using combination queries. Taking these two simple term queries:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-java\">MatchQuery bitterQuery = MatchQuery.on(\"beerIndex\").match(\"bitter\").field(\"description\").build();\r\nMatchQuery maltyQuery = MatchQuery.on(\"beerIndex\").match(\"malty\").field(\"description\").build();<\/code><\/pre>\n<\/div>\n<p>You could combine them in different manners:<\/p>\n<ul>\n<li>a <code>conjunction<\/code> looks for all the terms<\/li>\n<\/ul>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-java\"> ConjunctionQuery.on(\"beerIndex\").conjuncts(bitterQuery, maltyQuery)<\/code><\/pre>\n<\/div>\n<ul>\n<li>a <code>disjunction<\/code> looks for at least one term<\/li>\n<\/ul>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-java\"> DisjunctionQuery.on(\"beerIndex\").disjuncts(bitterQuery, maltyQuery)<\/code><\/pre>\n<\/div>\n<ul>\n<li>a <code>boolean query<\/code> allows you to combine the two approaches<\/li>\n<\/ul>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-java\"> BooleanQuery.on(\"beerIndex\").must(bitterQuery).mustNot(maltyQuery)<\/code><\/pre>\n<\/div>\n<h2 id=\"toc_10\">Getting Hit Explanations<\/h2>\n<p>If you want to get insights into the scoring and matching of a particular <code>SearchQueryRow<\/code>, you can build your query using the <code>.explain(true)<\/code> parameter and get details from the index in result&#8217;s <code>explanation()<\/code> field:<\/p>\n<div>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">{\"message\":\"sum of:\",\"children\":[{\"message\":\"product of:\",\"children\":[{\"message\":\"sum of:\",\"children\":[{\"message\":\"product of:\",\"children\":[{\"message\":\"sum of:\",\"children\":[\r\n{\r\n    \"message\": \"weight(_all:national^1.000000 in penn_brewery-penn_marzen), product of:\",\r\n    \"children\": [\r\n        {\r\n            \"message\": \"queryWeight(_all:national^1.000000), product of:\",\r\n            \"children\": [\r\n                {\r\n                    \"message\": \"boost\",\r\n                    \"value\": 1\r\n                },\r\n                {\r\n                    \"message\": \"idf(docFreq=17, maxDocs=7303)\",\r\n                    \"value\": 7.005668743723945\r\n                },\r\n                {\r\n                    \"message\": \"queryNorm\",\r\n                    \"value\": 0.1427415478209491\r\n                }\r\n            ],\r\n            \"value\": 0.9999999999999999\r\n        },\r\n        {\r\n            \"message\": \"fieldWeight(_all:national in penn_brewery-penn_marzen), product of:\",\r\n            \"children\": [\r\n                {\r\n                    \"message\": \"tf(termFreq(_all:national)=1\",\r\n                    \"value\": 1\r\n                },\r\n                {\r\n                    \"message\": \"fieldNorm(field=_all, doc=penn_brewery-penn_marzen)\",\r\n                    \"value\": 0.10000000149011612\r\n                },\r\n                {\r\n                    \"message\": \"idf(docFreq=17, maxDocs=7303)\",\r\n                    \"value\": 7.005668743723945\r\n                }\r\n            ],\r\n            \"value\": 0.7005668848116544\r\n        }\r\n    ],\r\n    \"value\": 0.7005668848116543\r\n}    ],\"value\":0.7005668848116543},{\"message\":\"coord(1\/1)\",\"value\":1}],\"value\":0.7005668848116543}],\"value\":0.7005668848116543},{\"message\":\"coord(1\/1)\",\"value\":1}],\"value\":0.7005668848116543}],\"value\":0.7005668848116543}<\/code><\/pre>\n<\/div>\n<h2 id=\"toc_11\">Conclusion<\/h2>\n<p>We hope that this preview of the API has peeked your interest!<\/p>\n<p>Go ahead and download the first <a href=\"https:\/\/www.couchbase.com\/4-5-dp\/\">Developer Preview of Couchbase 4.5<\/a> with embedded Full Text Search service. We hope that you&#8217;ll be able to quickly start searching using the associated <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/4.1\/sdks\/java-2.2\/download-links.html\">Java SDK API<\/a>.<\/p>\n<p>And until then&#8230; <strong>Happy coding!<\/strong><br \/>\n&#8211; <em>The Java SDK Team<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this blog post, we&#8217;ll have a look at the preview API for full text search in Couchbase 4.5. Please note that this API, released in the latest Java SDK \u00a0(2.2.4), is still @Experimental. We&#8217;ll cover: Full Text Search in [&hellip;]<\/p>\n","protected":false},"author":48,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1816,2165,1818],"tags":[1584,1583,1466],"ppma_author":[9022],"class_list":["post-2149","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-server","category-full-text-search","category-java","tag-bleve","tag-cbft","tag-preview"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Preview of Full Text Search in Couchbase using the Java SDK<\/title>\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\/pt\/cbftjavapreview\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Preview of Full Text Search in Couchbase using the Java SDK\" \/>\n<meta property=\"og:description\" content=\"In this blog post, we&#8217;ll have a look at the preview API for full text search in Couchbase 4.5. Please note that this API, released in the latest Java SDK \u00a0(2.2.4), is still @Experimental. We&#8217;ll cover: Full Text Search in [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/cbftjavapreview\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-02-24T17:06:22+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T03:59:48+00:00\" \/>\n<meta name=\"author\" content=\"Simon Basle, Software Engineer, Pivotal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Simon Basle, Software Engineer, Pivotal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cbftjavapreview\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cbftjavapreview\\\/\"},\"author\":{\"name\":\"Simon Basle, Software Engineer, Pivotal\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/a4086d75b59570cc2e5ff66d98c5d1a1\"},\"headline\":\"Preview of Full Text Search in Couchbase using the Java SDK\",\"datePublished\":\"2016-02-24T17:06:22+00:00\",\"dateModified\":\"2025-06-14T03:59:48+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cbftjavapreview\\\/\"},\"wordCount\":1090,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cbftjavapreview\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"keywords\":[\"bleve\",\"cbft\",\"preview\"],\"articleSection\":[\"Couchbase Server\",\"Full-Text Search\",\"Java\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cbftjavapreview\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cbftjavapreview\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cbftjavapreview\\\/\",\"name\":\"Preview of Full Text Search in Couchbase using the Java SDK\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cbftjavapreview\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cbftjavapreview\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2016-02-24T17:06:22+00:00\",\"dateModified\":\"2025-06-14T03:59:48+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cbftjavapreview\\\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cbftjavapreview\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cbftjavapreview\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/cbftjavapreview\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Preview of Full Text Search in Couchbase using the Java SDK\"}]},{\"@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\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@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\\\/a4086d75b59570cc2e5ff66d98c5d1a1\",\"name\":\"Simon Basle, Software Engineer, Pivotal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g4b2bcd169f85f21cee7b8a0e0c9e7854\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g\",\"caption\":\"Simon Basle, Software Engineer, Pivotal\"},\"description\":\"Simon Basl_ is a Paris-based Software Engineer working in the Spring team at Pivotal. Previously, he worked in the Couchbase Java SDK team. His interests span software design aspects (OOP, design patterns, software architecture), rich clients, what lies beyond code (continuous integration, (D)VCS, best practices), and reactive programming. He is also an editor for the French version of InfoQ.com.\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/pt\\\/author\\\/simon-basle\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Visualiza\u00e7\u00e3o da pesquisa de texto completo no Couchbase usando o Java SDK","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\/pt\/cbftjavapreview\/","og_locale":"pt_BR","og_type":"article","og_title":"Preview of Full Text Search in Couchbase using the Java SDK","og_description":"In this blog post, we&#8217;ll have a look at the preview API for full text search in Couchbase 4.5. Please note that this API, released in the latest Java SDK \u00a0(2.2.4), is still @Experimental. We&#8217;ll cover: Full Text Search in [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/cbftjavapreview\/","og_site_name":"The Couchbase Blog","article_published_time":"2016-02-24T17:06:22+00:00","article_modified_time":"2025-06-14T03:59:48+00:00","author":"Simon Basle, Software Engineer, Pivotal","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Simon Basle, Software Engineer, Pivotal","Est. reading time":"6 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/cbftjavapreview\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/cbftjavapreview\/"},"author":{"name":"Simon Basle, Software Engineer, Pivotal","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/a4086d75b59570cc2e5ff66d98c5d1a1"},"headline":"Preview of Full Text Search in Couchbase using the Java SDK","datePublished":"2016-02-24T17:06:22+00:00","dateModified":"2025-06-14T03:59:48+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/cbftjavapreview\/"},"wordCount":1090,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/cbftjavapreview\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["bleve","cbft","preview"],"articleSection":["Couchbase Server","Full-Text Search","Java"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/cbftjavapreview\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/cbftjavapreview\/","url":"https:\/\/www.couchbase.com\/blog\/cbftjavapreview\/","name":"Visualiza\u00e7\u00e3o da pesquisa de texto completo no Couchbase usando o Java SDK","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/cbftjavapreview\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/cbftjavapreview\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2016-02-24T17:06:22+00:00","dateModified":"2025-06-14T03:59:48+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/cbftjavapreview\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/cbftjavapreview\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/cbftjavapreview\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/cbftjavapreview\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Preview of Full Text Search in Couchbase using the Java SDK"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados NoSQL","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":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@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\/a4086d75b59570cc2e5ff66d98c5d1a1","name":"Simon Basle, engenheiro de software, Pivotal","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/secure.gravatar.com\/avatar\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g4b2bcd169f85f21cee7b8a0e0c9e7854","url":"https:\/\/secure.gravatar.com\/avatar\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g","caption":"Simon Basle, Software Engineer, Pivotal"},"description":"Simon Basl_ \u00e9 um engenheiro de software baseado em Paris que trabalha na equipe Spring da Pivotal. Anteriormente, ele trabalhou na equipe do Couchbase Java SDK. Seus interesses abrangem aspectos de design de software (OOP, padr\u00f5es de design, arquitetura de software), clientes avan\u00e7ados, o que est\u00e1 al\u00e9m do c\u00f3digo (integra\u00e7\u00e3o cont\u00ednua, (D)VCS, pr\u00e1ticas recomendadas) e programa\u00e7\u00e3o reativa. Ele tamb\u00e9m \u00e9 editor da vers\u00e3o francesa do InfoQ.com.","url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/simon-basle\/"}]}},"acf":[],"authors":[{"term_id":9022,"user_id":48,"is_guest":0,"slug":"simon-basle","display_name":"Simon Basle, Software Engineer, Pivotal","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/3c3aec94782fea5f0a199368c15e836198faf05c1591e0ae0b91178a59457781?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2149","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/48"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=2149"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2149\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=2149"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=2149"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=2149"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=2149"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}