{"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\/es\/cbftjavapreview\/","title":{"rendered":"Vista previa de la b\u00fasqueda de texto completo en Couchbase utilizando el SDK de Java"},"content":{"rendered":"<p>En esta entrada del blog, echaremos un vistazo a la API de vista previa para la b\u00fasqueda de texto completo en <a href=\"https:\/\/www.couchbase.com\/blog\/es\/next\/\"><strong>Couchbase 4.5<\/strong><\/a>. Tenga en cuenta que esta API, publicada en el \u00faltimo <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/4.1\/sdks\/java-2.2\/download-links.html\">SDK de Java <\/a>\u00a0(<code>2.2.4<\/code>), sigue siendo <code>@Experimental<\/code>.<\/p>\n<p>Cubriremos:<\/p>\n<ul class=\"toc\">\n<li><a href=\"#toc_0\">\u00bfB\u00fasqueda de texto completo en Couchbase?<\/a><\/li>\n<li><a href=\"#toc_1\">La API de Java<\/a><\/li>\n<li><a href=\"#toc_2\">Varios tipos de consultas<\/a>\n<ul>\n<li><a href=\"#toc_3\">Consulta difusa<\/a><\/li>\n<li><a href=\"#toc_4\">T\u00e9rminos m\u00faltiples: MatchPhrase<\/a><\/li>\n<li><a href=\"#toc_5\">Consulta Regexp<\/a><\/li>\n<li><a href=\"#toc_6\">Prefijo Consulta<\/a><\/li>\n<li><a href=\"#toc_7\">Consultas por rango y fecha<\/a><\/li>\n<li><a href=\"#toc_8\">Consulta gen\u00e9rica<\/a><\/li>\n<li><a href=\"#toc_9\">Combinaci\u00f3n de<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#toc_10\">Obtener explicaciones de los aciertos<\/a><\/li>\n<li><a href=\"#toc_11\">Conclusi\u00f3n<\/a><\/li>\n<\/ul>\n<p>Esta API experimental se puede utilizar con Couchbase Server 4.5 Developer Preview, siempre que se utilice la extensi\u00f3n <code>2.2.4<\/code>\u00a0Java SDK client, que puedes obtener a trav\u00e9s de Maven. A\u00f1ada la siguiente dependencia a su <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\">\u00bfB\u00fasqueda de texto completo en Couchbase?<\/h2>\n<p>S\u00ed. El pr\u00f3ximo <code>4.5<\/code> (nombre en clave Watson) incluir\u00e1 un indexador de texto completo (FTS, tambi\u00e9n conocido como CBFT) basado en el programa de c\u00f3digo abierto <a href=\"https:\/\/www.blevesearch.com\/\">Bleve<\/a> proyecto. Bleve trata sobre la b\u00fasqueda de texto completo y la indexaci\u00f3n en Go (un saludo a nuestro propio <a href=\"https:\/\/twitter.com\/mschoch\">Marty Schoch<\/a> por iniciar este proyecto).<\/p>\n<p>La idea es aprovechar Bleve para proporcionar una b\u00fasqueda de texto completo off-the-shelf en Couchbase Server, sin tener que utilizar conectores a software externo (que se ejecuta en su propio cl\u00faster). Si esa soluci\u00f3n \"off-the-shelf\" no satisface sus necesidades hasta el final, por supuesto, todav\u00eda puede utilizar estos <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/4.0\/connectors\/elasticsearch-2.1\/elastic-intro.html\">conectores<\/a>pero para las necesidades m\u00e1s sencillas se puede optar por una \u00fanica soluci\u00f3n.<\/p>\n<p>FTS ofrece una gran cantidad de capacidades que son proporcionadas por Bleve: Analizadores de texto, tokenizadores y filtros de tokens de posprocesamiento que van m\u00e1s all\u00e1 del alcance de este post, as\u00ed como los numerosos tipos de <em>consultas<\/em> que puede ejecutar en los \u00edndices resultantes. Veamos cu\u00e1les son esos tipos y c\u00f3mo puedes esperar utilizarlos en el contexto del SDK de Java.<\/p>\n<p>En el resto de esta entrada de blog, utilizaremos 3 \u00edndices que podr\u00e1 crear a trav\u00e9s de la consola de administraci\u00f3n web en la pr\u00f3xima versi\u00f3n 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>Esta es la lista de \u00edndices de la interfaz de usuario:<br \/>\n<img decoding=\"async\" src=\"\/wp-content\/original-assets\/2016\/february\/cbftjavapreview\/indexlist.png\" align=\"middle\" \/><br \/>\nTenemos:<\/p>\n<ul>\n<li>a <code>beerIndex<\/code> que indexa todo el contenido de cada documento del <code>`beer-sample`<\/code> cubo.<\/li>\n<li>a <code>travelIndex<\/code> que indexa todo el contenido de cada documento del <code>`viaje-muestra<\/code> cubo.<\/li>\n<li>un \u00edndice de alias, <code>commonIndex<\/code>que es una uni\u00f3n de los dos \u00edndices anteriores.<\/li>\n<\/ul>\n<h2 id=\"toc_1\">La API de Java<\/h2>\n<p>El punto de entrada de la funci\u00f3n de b\u00fasqueda de texto completo en el SDK de Java se encuentra en la carpeta <code>Cubo<\/code>utilizando el <code>query(SearchQuery ftq)<\/code> m\u00e9todo. Esto es coherente con los m\u00e9todos de consulta existentes ya presentes en la API para ejecutar un <code>ViewQuery<\/code> o un <code>N1qlQuery<\/code>.<\/p>\n<p>La API para la b\u00fasqueda de texto completo sigue el <em>constructor<\/em> patr\u00f3n. Identifique el tipo de consulta que desea y utilice el constructor correspondiente para construirla, obtenga la funci\u00f3n <code>B\u00fasquedaQuery<\/code> utilizando <code>construir()<\/code> y ejecutarlo utilizando <code>bucket.query(searchQuery)<\/code>.<\/p>\n<p>Tomemos un ejemplo (muy sencillo) y veamos c\u00f3mo se puede consumir:<\/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>Si examinamos cada secci\u00f3n por separado, esto es lo que ocurri\u00f3:<\/p>\n<ol>\n<li>Creamos un sencillo <code>MatchQuery<\/code> en un solo plazo.<\/li>\n<li>Se ejecuta en la muestra de cerveza (<code>.on(beerIndex<\/code>), busca apariciones textuales de la palabra \"nacional\" (<code>.query(\"nacional\")<\/code>) o t\u00e9rminos cercanos.<\/li>\n<li>Se realiza una configuraci\u00f3n adicional para limitar el n\u00famero de resultados a 3 (<code>l\u00edmite(3)<\/code>) y la consulta propiamente dicha se crea en este punto (<code>.construir()<\/code>).<\/li>\n<li>La consulta se ejecuta (<code>bucket.query(ftq)<\/code>) y devuelve un <code>SearchQueryResult<\/code>.<\/li>\n<li>Emitimos el resultado de <code>totalHits()<\/code> y las filas individuales (tambi\u00e9n accesibles como lista a trav\u00e9s de <code>aciertos()<\/code>).<\/li>\n<\/ol>\n<p>Ejecutando ese c\u00f3digo sale:<\/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>Vemos que el total de visitas nos da el n\u00famero real de visitas antes de que se aplicara el l\u00edmite. La direcci\u00f3n <code>aciertos()<\/code> devuelve 3 <code>B\u00fasquedaQueryRow<\/code> objetos, seg\u00fan lo solicitado.<\/p>\n<p>Cada acierto contiene la clave del documento asociado en Couchbase (<code>id()<\/code>), as\u00ed como m\u00e1s informaci\u00f3n sobre la coincidencia, por ejemplo, una puntuaci\u00f3n para la coincidencia (<code>puntuaci\u00f3n()<\/code>)... Si lo desea, puede recuperar el documento asociado utilizando <code>bucket.get(fila.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>Esto nos da, para el primer golpe:<\/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>Si observamos detenidamente el JSON del documento, nos daremos cuenta de d\u00f3nde probablemente coincid\u00eda el documento. En el campo \"<code>descripci\u00f3n<\/code>\" del documento, aparece esta frase:<\/p>\n<blockquote><p>La primera cervecer\u00eda que abri\u00f3 sus puertas en <strong>naci\u00f3n<\/strong>desde la Prohibici\u00f3n.<\/p><\/blockquote>\n<p>Observe tambi\u00e9n que la consulta de texto busc\u00f3 la palabra solicitada y las palabras derivadas que tienen la misma ra\u00edz. En realidad, aplic\u00f3 una imprecisi\u00f3n de 2 (v\u00e9ase la secci\u00f3n siguiente).<\/p>\n<p>Este patr\u00f3n tambi\u00e9n puede aplicarse a otros tipos de consulta, as\u00ed que veamos algunos m\u00e1s para ver qu\u00e9 tipo de b\u00fasqueda puede realizarse.<\/p>\n<h2 id=\"toc_2\">Varios tipos de consultas<\/h2>\n<h2 id=\"toc_3\">Consulta difusa<\/h2>\n<p>La consulta difusa puede realizarse con la funci\u00f3n <code>MatchQuery<\/code>especificando un <a href=\"https:\/\/en.wikipedia.org\/wiki\/Levenshtein_distance\">Distancia Levenshtein<\/a> como m\u00e1ximo <code>imprecisi\u00f3n()<\/code> permitir en el plazo:<\/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>A un nivel de <strong>2<\/strong>Esto coincide con palabras como \"martillo\", \"mam\u00e1\" o \"verano\":<\/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>A un nivel de <strong>1<\/strong>no se encuentra ninguna coincidencia:<\/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>Tambi\u00e9n se ofrece un tipo de consulta dedicada a la imprecisi\u00f3n y que no aplica ning\u00fan analizador en el <code>FuzzyQuery<\/code>.<\/p>\n<h2 id=\"toc_4\">T\u00e9rminos m\u00faltiples: MatchPhrase<\/h2>\n<p>Como hemos visto, <code>MatchQuery<\/code> es una consulta basada en t\u00e9rminos que permite especificar opcionalmente la imprecisi\u00f3n y tambi\u00e9n aplica al t\u00e9rmino buscado el mismo filtro que se haya podido aplicar al campo (por ejemplo, stemming, etc...):<\/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>Puede buscar varios t\u00e9rminos en una sola consulta utilizando un atributo <code>Frase de partido<\/code> consulta. Se analizan los t\u00e9rminos y se puede activar opcionalmente la imprecisi\u00f3n:<\/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\">Consulta Regexp<\/h2>\n<p>A <code>RegexpQuery<\/code> no s\u00f3lo hace coincidencias literales, sino que permite hacer coincidencias utilizando una expresi\u00f3n regular. Tome este ejemplo:<\/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>Observe que esta consulta se dirige a un campo concreto del archivo json (<code>campo(\"nombre\")<\/code>). Queremos todos los nombres que contengan \"cuento\" o \"p\u00e1lido\". He aqu\u00ed algunos nombres que coinciden con esta b\u00fasqueda:<\/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\">Prefijo Consulta<\/h2>\n<p>A <code>PrefixQuery<\/code> busca apariciones de palabras que empiecen por la cadena dada:<\/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>Una vez m\u00e1s, s\u00f3lo miramos dentro del <code>nombre<\/code> campo, esta vez para las palabras que empiezan por \"weiss\":<\/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\">Consultas por rango y fecha<\/h2>\n<p><code>FTS<\/code> tambi\u00e9n funciona bien con datos no textuales. Por ejemplo, el <code>NumericRangeQuery<\/code> permite buscar valores num\u00e9ricos dentro de un intervalo proporcionado:<\/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>Qu\u00e9 salidas:<\/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>Las fechas tambi\u00e9n se cubren con el <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>Qu\u00e9 salidas:<\/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\">Consulta gen\u00e9rica<\/h2>\n<p><code>FTS<\/code> tambi\u00e9n ofrecen una forma m\u00e1s gen\u00e9rica de consulta que combina frases, t\u00e9rminos y m\u00e1s utilizando la funci\u00f3n <a href=\"https:\/\/www.blevesearch.com\/docs\/Query-String-Query\/\"><code>Cadena Sintaxis de consulta<\/code><\/a>. Se puede acceder a \u00e9l en la API a trav\u00e9s de la funci\u00f3n <code>StringQuery<\/code>.<\/p>\n<h2 id=\"toc_9\">Combinaci\u00f3n de<\/h2>\n<p>Adem\u00e1s, puede combinar criterios sencillos como <code>MatchQuery<\/code> mediante consultas combinadas. Tomando estas dos simples consultas de t\u00e9rminos:<\/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>Puedes combinarlos de diferentes maneras:<\/p>\n<ul>\n<li>a <code>conjunci\u00f3n<\/code> busca todos los t\u00e9rminos<\/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>disyunci\u00f3n<\/code> busca al menos un t\u00e9rmino<\/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>consulta booleana<\/code> permite combinar los dos enfoques<\/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\">Obtener explicaciones de los aciertos<\/h2>\n<p>Si desea obtener informaci\u00f3n sobre la puntuaci\u00f3n y el emparejamiento de un determinado <code>B\u00fasquedaQueryRow<\/code>puede construir su consulta utilizando la funci\u00f3n <code>.explain(true)<\/code> y obtener los detalles del \u00edndice en el par\u00e1metro <code>explicaci\u00f3n()<\/code> campo:<\/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\">Conclusi\u00f3n<\/h2>\n<p>Esperamos que este avance de la API haya despertado su inter\u00e9s.<\/p>\n<p>Desc\u00e1rguese el primer <a href=\"https:\/\/www.couchbase.com\/blog\/es\/4-5-dp\/\">Vista previa para desarrolladores de Couchbase 4.5<\/a> con servicio integrado de b\u00fasqueda de texto completo. Esperamos que pueda empezar a buscar r\u00e1pidamente utilizando el servicio asociado <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/4.1\/sdks\/java-2.2\/download-links.html\">API del SDK de Java<\/a>.<\/p>\n<p>Y hasta entonces... <strong>\u00a1Feliz codificaci\u00f3n!<\/strong><br \/>\n&#8211; <em>El equipo del SDK de Java<\/em><\/p>","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>","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"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.0 (Yoast SEO v26.0) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\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\/es\/cbftjavapreview\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\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\/es\/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\":\"es\",\"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\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/cbftjavapreview\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@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\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@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\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4b2bcd169f85f21cee7b8a0e0c9e7854\",\"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\/es\/author\/simon-basle\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Vista previa de la b\u00fasqueda de texto completo en Couchbase utilizando el SDK de Java","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\/es\/cbftjavapreview\/","og_locale":"es_MX","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\/es\/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":"es","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":"Vista previa de la b\u00fasqueda de texto completo en Couchbase utilizando el SDK de Java","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":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/cbftjavapreview\/"]}]},{"@type":"ImageObject","inLanguage":"es","@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":"El blog de Couchbase","description":"Couchbase, la base de datos 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":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"El blog de Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@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, Ingeniero de Software, Pivotal","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4b2bcd169f85f21cee7b8a0e0c9e7854","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_ es un Ingeniero de Software residente en Par\u00eds que trabaja en el equipo Spring de Pivotal. Anteriormente, trabaj\u00f3 en el equipo de Couchbase Java SDK. Sus intereses abarcan aspectos de dise\u00f1o de software (OOP, patrones de dise\u00f1o, arquitectura de software), clientes ricos, lo que hay m\u00e1s all\u00e1 del c\u00f3digo (integraci\u00f3n continua, (D)VCS, mejores pr\u00e1cticas) y programaci\u00f3n reactiva. Tambi\u00e9n es editor de la versi\u00f3n francesa de InfoQ.com.","url":"https:\/\/www.couchbase.com\/blog\/es\/author\/simon-basle\/"}]}},"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","author_category":"","last_name":"Basle","first_name":"Simon","job_title":"","user_url":"","description":"Simon Basl_ es un Ingeniero de Software residente en Par\u00eds que trabaja en el equipo Spring de Pivotal. Anteriormente, trabaj\u00f3 en el equipo de Couchbase Java SDK. Sus intereses abarcan aspectos de dise\u00f1o de software (OOP, patrones de dise\u00f1o, arquitectura de software), clientes ricos, lo que hay m\u00e1s all\u00e1 del c\u00f3digo (integraci\u00f3n continua, (D)VCS, mejores pr\u00e1cticas) y programaci\u00f3n reactiva. Tambi\u00e9n es editor de la versi\u00f3n francesa de InfoQ.com."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2149","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/48"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=2149"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2149\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=2149"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=2149"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=2149"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=2149"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}