{"id":2871,"date":"2017-03-01T08:46:35","date_gmt":"2017-03-01T16:46:35","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2871"},"modified":"2025-06-13T20:28:13","modified_gmt":"2025-06-14T03:28:13","slug":"using-couchbase-full-text-search-service-java","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-full-text-search-service-java\/","title":{"rendered":"Uso del servicio de b\u00fasqueda de texto completo Couchbase en Java"},"content":{"rendered":"<p><em><a href=\"https:\/\/www.linkedin.com\/in\/ratnopam-chakrabarti\" target=\"_blank\" rel=\"noopener\">Ratnopam Chakrabarti<\/a><\/em><em>\u00a0es un desarrollador de software que trabaja actualmente para Ericsson Inc. Lleva bastante tiempo centrado en IoT, tecnolog\u00edas m\u00e1quina a m\u00e1quina, coches conectados y dominios de ciudades inteligentes. Le encanta aprender nuevas tecnolog\u00edas y ponerlas en pr\u00e1ctica. Cuando no est\u00e1 trabajando, le gusta pasar tiempo con su hijo de 3 a\u00f1os.<\/em><\/p>\n<p>La b\u00fasqueda basada en texto completo es una funci\u00f3n que permite a los usuarios realizar b\u00fasquedas basadas en textos y palabras clave, y es muy popular entre los usuarios y la comunidad de desarrolladores. Por lo tanto, es obvio que hay muchas API y frameworks que ofrecen b\u00fasquedas de texto completo, como Apache Solr, Lucene y Elasticsearch, por nombrar solo algunos. <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/fts\/full-text-intro.html\">Couchbase<\/a>uno de los principales gigantes de NoSQL, comenz\u00f3 a implementar esta funci\u00f3n en su versi\u00f3n 4.5 de Couchbase Server.<\/p>\n<p>En este post, voy a describir c\u00f3mo integrar el servicio de b\u00fasqueda de texto completo en su aplicaci\u00f3n utilizando el m\u00f3dulo <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/sdk\/java\/start-using-sdk.html\">SDK Java de Couchbase<\/a>.<\/p>\n<h4>Puesta en marcha<\/h4>\n<p>Vaya a start.spring.io y seleccione Couchbase como dependencia en su aplicaci\u00f3n Spring boot.<\/p>\n<p>Una vez que tengas el proyecto configurado, deber\u00edas ver la siguiente dependencia en tu archivo de modelo de objetos del proyecto (pom.xml). Asegura que todas las librer\u00edas de Couchbase est\u00e1n en su lugar para la aplicaci\u00f3n.<\/p>\n<p>&lt;dependency&gt;<\/p>\n<p>org.springframework.boot<\/p>\n<p>spring-boot-starter-data-couchbase<\/p>\n<p>&lt;\/dependency&gt;<\/p>\n<p>Es necesario configurar un bucket de Couchbase para alojar el conjunto de datos de muestra en el que realizar la b\u00fasqueda.<\/p>\n<p>He creado un bucket llamado \"conference\" en la consola de administraci\u00f3n de Couchbase.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/02\/pasted-image-0.png\" alt=\"Couchbase admin console\" width=\"1139\" height=\"374\" \/><\/p>\n<p>El bucket \"conferencia\" tiene actualmente tres documentos, y contienen datos sobre diferentes conferencias celebradas en todo el mundo. Si desea experimentar, puede ampliar este modelo de datos o crear uno propio. Por ejemplo, los curr\u00edculos, los cat\u00e1logos de productos o incluso los tweets son un buen caso de uso para la b\u00fasqueda de texto completo. Sin embargo, vamos a ce\u00f1irnos a los datos de las conferencias, como se muestra a continuaci\u00f3n:<\/p>\n<p><code><br \/>\n{<\/code><\/p>\n<p>\"title\": \"DockerCon\",<\/p>\n<p>\"tipo\": \"Conferencia\",<\/p>\n<p>\"localizaci\u00f3n\": \"Austin\",<\/p>\n<p>\"inicio\": \"04\/17\/2017\",<\/p>\n<p>\"end\": \"04\/20\/2017\",<\/p>\n<p>\"topics\": [<\/p>\n<p>\"contenedores\",<\/p>\n<p>\"devops\",<\/p>\n<p>\"microservicios\",<\/p>\n<p>\"desarrollo de productos\",<\/p>\n<p>\"virtualizaci\u00f3n\"<\/p>\n<p>],<\/p>\n<p>\"asistentes\": 20000,<\/p>\n<p>\"resumen\": \"DockerCon contar\u00e1 con temas y contenidos que cubren todos los aspectos de Docker y su ecosistema y ser\u00e1 adecuado para desarrolladores, DevOps, administradores de sistemas y ejecutivos de nivel C\",<\/p>\n<p>\"social\": {<\/p>\n<p>\"facebook\": \"https:\/\/www.facebook.com\/dockercon\",<\/p>\n<p>\"twitter\": \"https:\/\/www.twitter.com\/dockercon\"<\/p>\n<p>},<\/p>\n<p>\"altavoces\": [<\/p>\n<p>{<\/p>\n<p>\"Nombre\": \"Arun Gupta\",<\/p>\n<p>\"talk\": \"Docker con couchbase\",<\/p>\n<p>\"date\": \"04\/18\/2017\",<\/p>\n<p>\"duraci\u00f3n\": \"2\"<\/p>\n<p>},<\/p>\n<p>{<\/p>\n<p>\"Nombre\": \"Laura Frank\",<\/p>\n<p>\"hablar\": \"Opensource\",<\/p>\n<p>\"date\": \"04\/19\/2017\",<\/p>\n<p>\"duraci\u00f3n\": \"2\"<\/p>\n<p>}<\/p>\n<p>]<\/p>\n<p>}<\/p>\n<p>Para poder utilizar la b\u00fasqueda de texto completo en el conjunto de datos anterior, primero debe crear un \u00edndice de b\u00fasqueda de texto completo. Realice los siguientes pasos:<\/p>\n<p>En la consola de administraci\u00f3n de Couchbase, haga clic en la pesta\u00f1a \u00cdndices.<\/p>\n<p>Haga clic en el enlace Texto completo, que mostrar\u00e1 una lista de los \u00edndices de texto completo actuales.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/02\/pasted-image-0-4.png\" alt=\"text indexes Image\" width=\"1160\" height=\"288\" \/><\/p>\n<p>Como puedes adivinar, he creado un \u00edndice llamado \"conference-search\" que utilizar\u00eda desde el c\u00f3digo Java para buscar los datos relacionados con la conferencia.<\/p>\n<p>Haga clic en el bot\u00f3n Nuevo \u00edndice de texto completo para crear un nuevo \u00edndice.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/02\/pasted-image-0-1.png\" alt=\"pasted image 0 1\" \/><\/p>\n<p>S\u00ed, es as\u00ed de f\u00e1cil. Una vez creado el \u00edndice, ya puedes utilizarlo desde la aplicaci\u00f3n que est\u00e9s creando.<\/p>\n<p>Antes de sumergirnos en el c\u00f3digo, echemos un vistazo a los otros dos documentos que ya est\u00e1n en el cubo.<\/p>\n<p><code><br \/>\nConferencia::2<\/code><\/p>\n<p>{<\/p>\n<p>\"t\u00edtulo\": \"Devoxx UK\",<\/p>\n<p>\"tipo\": \"Conferencia\",<\/p>\n<p>\"localizaci\u00f3n\": \"B\u00e9lgica\",<\/p>\n<p>\"inicio\": \"05\/11\/2017\",<\/p>\n<p>\"fin\": \"05\/12\/2017\",<\/p>\n<p>\"topics\": [<\/p>\n<p>\"nube\",<\/p>\n<p>\"iot\",<\/p>\n<p>\"big data\",<\/p>\n<p>\"aprendizaje autom\u00e1tico\",<\/p>\n<p>\"realidad virtual\"<\/p>\n<p>],<\/p>\n<p>\"asistentes\": 10000,<\/p>\n<p>\"resumen\": \"Devoxx UK vuelve a Londres en 2017. Una vez m\u00e1s, daremos la bienvenida a ponentes y asistentes incre\u00edbles para ofrecer el mejor contenido para desarrolladores y experiencias incre\u00edbles\",<\/p>\n<p>\"social\": {<\/p>\n<p>\"facebook\": \"https:\/\/www.facebook.com\/devoxxUK\",<\/p>\n<p>\"twitter\": \"https:\/\/www.twitter.com\/devoxxUK\"<\/p>\n<p>},<\/p>\n<p>\"altavoces\": [<\/p>\n<p>{<\/p>\n<p>\"Nombre\": \"Viktor Farcic\",<\/p>\n<p>\"hablar\": \"Cloudbees\",<\/p>\n<p>\"date\": \"05\/11\/2017\",<\/p>\n<p>\"duraci\u00f3n\": \"2\"<\/p>\n<p>},<\/p>\n<p>{<\/p>\n<p>\"Nombre\": \"Patrick Kua\",<\/p>\n<p>\"hablar\": \"Thoughtworks\",<\/p>\n<p>\"date\": \"05\/12\/2017\",<\/p>\n<p>\"duraci\u00f3n\": \"2\"<\/p>\n<p>}<\/p>\n<p>]<\/p>\n<p>}<\/p>\n<p>&nbsp;<\/p>\n<p>Conferencia::3<\/p>\n<p>{<\/p>\n<p>\"t\u00edtulo\": \"ReInvent\",<\/p>\n<p>\"tipo\": \"Conferencia\",<\/p>\n<p>\"localizaci\u00f3n\": \"Las Vegas\",<\/p>\n<p>\"inicio\": \"11\/28\/2017\",<\/p>\n<p>\"end\": \"11\/30\/2017\",<\/p>\n<p>\"topics\": [<\/p>\n<p>\"aws\",<\/p>\n<p>\"sin servidor\",<\/p>\n<p>\"microservicios\",<\/p>\n<p>\"computaci\u00f3n en nube\",<\/p>\n<p>\"realidad aumentada\"<\/p>\n<p>],<\/p>\n<p>\"asistentes\": 30000,<\/p>\n<p>\"resumen\": \"Aamazon web services reInvent 2017 promete un recinto m\u00e1s grande, m\u00e1s sesiones y un enfoque en tecnolog\u00edas como microservicios y Lambda.\",<\/p>\n<p>\"social\": {<\/p>\n<p>\"facebook\": \"https:\/\/www.facebook.com\/reinvent\",<\/p>\n<p>\"twitter\": \"https:\/\/www.twitter.com\/reinvent\"<\/p>\n<p>},<\/p>\n<p>\"altavoces\": [<\/p>\n<p>{<\/p>\n<p>\"Nombre\": \"Ryan K\",<\/p>\n<p>\"talk\": \"Amazon Alexa\",<\/p>\n<p>\"date\": \"11\/28\/2017\",<\/p>\n<p>\"duraci\u00f3n\": \"2.5\"<\/p>\n<p>},<\/p>\n<p>{<\/p>\n<p>\"Nombre\": \"Anthony J\",<\/p>\n<p>\"hablar\": \"Lambda\",<\/p>\n<p>\"date\": \"11\/29\/2017\",<\/p>\n<p>\"duraci\u00f3n\": \"1.5\"<\/p>\n<p>}<\/p>\n<p>]<\/p>\n<p>}<\/p>\n<h4>Invocar la b\u00fasqueda de texto completo desde c\u00f3digo Java<\/h4>\n<h5>Conectarse al bucket Couchbase desde el c\u00f3digo<\/h5>\n<p>Spring boot ofrece una forma c\u00f3moda de conectar con el entorno Couchbase permiti\u00e9ndonos especificar ciertos detalles del entorno Couchbase como una configuraci\u00f3n de Spring. Normalmente especificamos los siguientes par\u00e1metros en el archivo application.properties:<\/p>\n<p>spring.couchbase.bootstrap-hosts=127.0.0.1<br \/>\nspring.couchbase.bucket.name=conferencia<br \/>\nspring.couchbase.bucket.password=<\/p>\n<p>Aqu\u00ed, he especificado mi ip localhost ya que estoy ejecutando Couchbase Server en mi port\u00e1til. Nota: Puedes ejecutar Couchbase como un contenedor Docker proporcionando la direcci\u00f3n IP del contenedor.<\/p>\n<p>El nombre del bucket tiene que coincidir con el nombre del bucket creado usando la consola de Couchbase.<\/p>\n<p>Tambi\u00e9n podemos especificar un cluster de direcciones IP como bootstrap-hosts. Spring proporcionar\u00e1 un cluster de entorno Couchbase con todos los nodos ejecutando Couchbase en ellos. Si se estableci\u00f3 una contrase\u00f1a cuando se cre\u00f3 el bucket, tambi\u00e9n podemos especificarla; de lo contrario, deja ese campo vac\u00edo. En nuestro caso, lo dejamos vac\u00edo.<\/p>\n<p>Para ejecutar una consulta contra el bucket deseado, primero necesitamos tener una referencia al objeto bucket. Y la configuraci\u00f3n de spring-couchbase hace todo el trabajo pesado entre bastidores por nosotros. Todo lo que tenemos que hacer es inyectar el bucket desde el constructor dentro de la clase Spring service bean.<\/p>\n<p>Aqu\u00ed est\u00e1 el c\u00f3digo:<\/p>\n<p><code><br \/>\n@Servicio<\/code><\/p>\n<p>public class Servicio de b\u00fasqueda de texto completo {<\/p>\n<p>privado Bucket bucket;<\/p>\n<p>public FullTextSearchService(Bucket bucket) {<\/p>\n<p>this.bucket = bucket;<\/p>\n<p>log.info(\"******** Cubo :: = \" + cubo.nombre());<\/p>\n<p>}<\/p>\n<p>public void findByTextMatch(String searchText) throws Exception {<\/p>\n<p>SearchQueryResult result = getBucket().query(<\/p>\n<p>new SearchQuery(FtsConstants.FTS_IDX_CONF, SearchQuery.matchPhrase(searchText)).fields(\"summary\"));<\/p>\n<p>for (SearchQueryRow hit : result.hits()) {<\/p>\n<p>log.info(\"****** puntuaci\u00f3n := \" + hit.puntuaci\u00f3n() + \" y contenido := \"<\/p>\n<p>+ bucket.get(hit.id()).content().get(\"title\"));<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>Tambi\u00e9n podemos personalizar algunos de los par\u00e1metros de configuraci\u00f3n de CouchbaseEnvironment. Para una lista detallada de los par\u00e1metros que podemos personalizar, echa un vistazo a lo siguiente <a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/current\/reference\/html\/boot-features-nosql.html\">directrices de referencia<\/a>:<\/p>\n<p>En este punto, podemos invocar el servicio desde el archivo <em>CommandLineRunner <\/em>frijol.<\/p>\n<p><code><br \/>\n@Configuraci\u00f3n<\/code><\/p>\n<p>public class FtsRunner implements CommandLineRunner {<\/p>\n<p>@Autowired<\/p>\n<p>FullTextSearchService fts;<\/p>\n<p>@Override<\/p>\n<p>public void run(String... arg0) throws Exception {<\/p>\n<p>fts.findByTextMatch(\"desarrollador\");<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<h5>Utilizar el servicio de b\u00fasqueda de texto completo<\/h5>\n<p>En el n\u00facleo del SDK de Java, Couchbase ofrece <em>consulta()<\/em>\u00a0como una forma de consulta en un cubo especificado. Si est\u00e1 familiarizado con N1QL Query o View Query, entonces el m\u00e9todo <em>consulta() <\/em>ofrece un patr\u00f3n similar; la \u00fanica diferencia para Search es que acepta un m\u00e9todo <em>B\u00fasquedaQuery <\/em>como argumento.<\/p>\n<p>A continuaci\u00f3n se muestra el c\u00f3digo que busca un texto determinado en el cubo \"conferencia\". <em>getBucket() <\/em>devuelve un asa del cubo.<\/p>\n<p>Al crear una SearchQuery, debe proporcionar el nombre del \u00edndice que cre\u00f3 en la secci\u00f3n Configuraci\u00f3n anterior. Aqu\u00ed, estoy utilizando \"conference-search\" como el \u00edndice que se especifica en el FtsConstants.FTS_IDX_CONF. Por cierto, el c\u00f3digo fuente completo de la aplicaci\u00f3n est\u00e1 cargado en GitHub y disponible para su descarga. El enlace est\u00e1 al final del post.<\/p>\n<p><code><br \/>\npublic static void findByTextMatch(String searchText) throws Exception {<\/code><\/p>\n<p>SearchQueryResult result = getBucket().query(new SearchQuery(FtsConstants.FTS_IDX_CONF, SearchQuery.matchPhrase(searchText)).fields(\"summary\"));<\/p>\n<p>log.info(\"****** total aciertos := \"+ resultado.aciertos().tama\u00f1o());<\/p>\n<p>for (SearchQueryRow hit : result.hits()) {<\/p>\n<p>log.info(\"****** puntuaci\u00f3n := \" + hit.puntuaci\u00f3n() + \" y contenido := \"+ bucket.get(hit.id()).contenido().get(\"t\u00edtulo\"));<\/p>\n<p>}<\/p>\n<p>}<\/p>\n<p>El c\u00f3digo anterior busca en el campo \"summary\" de los documentos del bucket utilizando la funci\u00f3n <em>matchPhrase(searchText) <\/em>m\u00e9todo.<\/p>\n<p>El c\u00f3digo se invoca mediante una simple llamada:<\/p>\n<p><em>findByTextMatch(\"desarrollador\");<\/em><\/p>\n<p>As\u00ed, la b\u00fasqueda de texto completo debe devolver todos los documentos del bucket de conferencias que tengan el texto \"desarrollador\" en su campo de resumen. Este es el resultado:<\/p>\n<p>Conferencia del cubo abierto<\/p>\n<p>****** total aciertos := 1<\/p>\n<p>****** puntuaci\u00f3n := 0.036940739161339185 y contenido := Devoxx UK<\/p>\n<p>El total de aciertos representa el n\u00famero total de coincidencias encontradas. Aqu\u00ed es 1 y tambi\u00e9n se puede encontrar la puntuaci\u00f3n correspondiente a esa coincidencia. El c\u00f3digo no imprime todo el documento, s\u00f3lo el t\u00edtulo de la conferencia. Si lo desea, puede imprimir los dem\u00e1s atributos del documento.<\/p>\n<p>Existen otras formas de utilizar SearchQuery que se describen a continuaci\u00f3n.<\/p>\n<h4>B\u00fasqueda de texto difuso<\/h4>\n<p>Puede realizar una consulta difusa especificando un m\u00e1ximo de <u><a href=\"https:\/\/en.wikipedia.org\/wiki\/Levenshtein_distance\" target=\"_blank\" rel=\"noopener\">Distancia Levenshtein<\/a><\/u>\u00a0como el m\u00e1ximo fuzziness() a permitir en el t\u00e9rmino. El valor predeterminado es 2.<\/p>\n<p>Por ejemplo, digamos que quiero encontrar la conferencia en la que \"sysops\" es uno de los \"temas\". En el conjunto de datos anterior, se puede ver que no hay temas \"sysops\" en ninguna de las conferencias. La coincidencia m\u00e1s cercana es \"devops\"; sin embargo, est\u00e1 a 3 distancias de Levenshtein. Por tanto, si ejecuto el siguiente c\u00f3digo con fuzziness 1 o 2, no deber\u00eda obtener ning\u00fan resultado, y no lo hace.<\/p>\n<p><code><br \/>\nSearchQueryResult resultFuzzy = getBucket().query(new SearchQuery(FtsConstants.FTS_IDX_CONF, SearchQuery.match(searchText).fuzziness(<strong>2<\/strong>)).fields(\"topics\"));<\/code><\/p>\n<p>log.info(\"****** total aciertos := \"+ resultFuzzy.aciertos().tama\u00f1o());<\/p>\n<p>for (SearchQueryRow hit : resultFuzzy.hits()) {<\/p>\n<p>log.info(\"****** puntuaci\u00f3n := \" + hit.puntuaci\u00f3n() + \" y contenido := \"+ bucket.get(hit.id()).contenido().get(\"temas\"));<\/p>\n<p>}<\/p>\n<p>findByTextFuzzy(\"sysops\"); da el siguiente resultado:<\/p>\n<p><strong>total aciertos := 0<\/strong><\/p>\n<p>Ahora, si cambio la borrosidad a \"3\" y vuelvo a invocar el mismo c\u00f3digo, me devuelve un documento. All\u00e1 va:<\/p>\n<p><strong>\u00a0****** total aciertos := 1<\/strong><\/p>\n<p>****** puntuaci\u00f3n := 0.016616112953992054 y contenido := [\"contenedores\",\"<strong>devops<\/strong>\", \"microservicios\", \"desarrollo de productos\", \"virtualizaci\u00f3n\"]<\/p>\n<p>Dado que \"devops\" coincide con \"sysops\" con una imprecisi\u00f3n de 3, la b\u00fasqueda es capaz de encontrar el documento.<\/p>\n<h4>Consulta de expresiones regulares<\/h4>\n<p>Puede realizar consultas basadas en expresiones regulares utilizando SearchQuery. El siguiente c\u00f3digo utiliza la funci\u00f3n <em>RegExpQuery <\/em>para buscar en \"temas\" basados en un patr\u00f3n suministrado.<br \/>\n<code><br \/>\nRegexpQuery rq = new RegexpQuery(regexp).field(\"topics\");<\/code><\/p>\n<p>SearchQueryResult resultRegExp = getBucket().query(new SearchQuery(FtsConstants.FTS_IDX_CONF, rq));<\/p>\n<p>log.info(\"****** total aciertos := \"+ resultadoRegExp.aciertos().tama\u00f1o());<\/p>\n<p>for (SearchQueryRow hit : resultRegExp.hits()) {<\/p>\n<p>log.info(\"****** puntuaci\u00f3n := \" + hit.puntuaci\u00f3n() + \" y contenido := \"+ bucket.get(hit.id()).contenido().get(\"temas\"));<\/p>\n<p>}<\/p>\n<p>Cuando se invoca como<\/p>\n<p>findByRegExp(\"[a-z]*\\s*realidad\");<\/p>\n<p>Devuelve los 2 documentos siguientes:<\/p>\n<p><strong>****** total aciertos := 2<\/strong><\/p>\n<p>****** puntuaci\u00f3n := 0.11597946228887497 y contenido := [\"aws\", \"serverless\", \"microservicios\", \"cloud computing\",\"<strong>realidad aumentada<\/strong>&#8220;]<\/p>\n<p>****** puntuaci\u00f3n := 0.1084888528694293 y contenido := [\"nube\", \"iot\", \"big data\", \"aprendizaje autom\u00e1tico\",\"<strong>realidad virtual<\/strong>&#8220;]<\/p>\n<h4>Consulta por prefijo<\/h4>\n<p>Couchbase permite realizar consultas basadas en el \"prefijo\" de un elemento de texto. La API busca textos que empiecen por el prefijo especificado. El c\u00f3digo es sencillo de utilizar; busca en el campo \"resumen\" del documento los textos que tienen el prefijo suministrado.<\/p>\n<p><code><br \/>\nPrefixQuery pq = new PrefixQuery(prefijo).campo(\"resumen\");<\/code><\/p>\n<p>SearchQueryResult resultPrefix = getBucket().query(new SearchQuery(FtsConstants.FTS_IDX_CONF, pq).fields(\"summary\"));<\/p>\n<p>log.info(\"****** total aciertos :=\"+ resultadoPrefijo.aciertos().tama\u00f1o());<\/p>\n<p>for (SearchQueryRow hit : resultPrefix.hits()) {<\/p>\n<p>log.info(\"****** puntuaci\u00f3n := \" + hit.puntuaci\u00f3n() + \" y contenido := \"+ bucket.get(hit.id()).contenido().get(\"resumen\"));<\/p>\n<p>}<\/p>\n<p>Si invoca el c\u00f3digo como findByPrefix(\"micro\");<\/p>\n<p>Obtendr\u00e1 el siguiente resultado:<\/p>\n<p><strong>\u00a0****** total aciertos := 1<\/strong><\/p>\n<p>****** puntuaci\u00f3n := 0.08200986407165835 y contenido := Servicios web de Aamazon reInvent 2017 promete un recinto m\u00e1s grande, m\u00e1s sesiones y un enfoque en tecnolog\u00edas como <strong>microservicios<\/strong>\u00a0y Lambda.<\/p>\n<h4>Consulta por frases<\/h4>\n<p>El c\u00f3digo siguiente permite consultar una frase en un texto.<\/p>\n<p><code><br \/>\nMatchPhraseQuery mpq = new MatchPhraseQuery(matchPhrase).field(\"altavoces.hablar\");<\/code><\/p>\n<p>SearchQueryResult resultPrefix = getBucket().query(new SearchQuery(FtsConstants.FTS_IDX_CONF, mpq).fields(\"altavoces.hablar\"));<\/p>\n<p>log.info(\"****** total aciertos :=\"+ resultadoPrefijo.aciertos().tama\u00f1o());<\/p>\n<p>for (SearchQueryRow hit : resultPrefix.hits()) {<\/p>\n<p>log.info(\"****** puntuaci\u00f3n := \" + hit.puntuaci\u00f3n() + \" y contenido := \"+ bucket.get(hit.id()).contenido().get(\"t\u00edtulo\") + \" oradores = \"+bucket.get(hit.id()).contenido().get(\"oradores\"));<\/p>\n<p>}<\/p>\n<p>Aqu\u00ed, la consulta busca una frase en el campo \"speakers.talk\" y devuelve la coincidencia si la encuentra.<\/p>\n<p>Un ejemplo de invocaci\u00f3n del c\u00f3digo anterior con<\/p>\n<p>findByMatchPhrase(\"Docker with couchbase\") da el siguiente resultado esperado:<\/p>\n<p><strong>****** total aciertos := 1<\/strong><\/p>\n<p>****** score := 0.25054427342401087 and content := DockerCon speakers = [{\"duration\": \"2\u2033, \"date\": \"04\/18\/2017\u2033, \"talk\":\"<strong>Docker con couchbase<\/strong>\", \"name\": \"Arun Gupta\"},{\"duration\": \"2\u2033, \"date\": \"04\/19\/2017\u2033, \"talk\": \"Opensource\", \"name\": \"Laura Frank\"}]<\/p>\n<h4>Consulta de rangos<\/h4>\n<p>La b\u00fasqueda de texto completo tambi\u00e9n es muy \u00fatil cuando se trata de realizar b\u00fasquedas por rangos, ya sean num\u00e9ricos o de fechas. Por ejemplo, si desea averiguar las conferencias cuyo n\u00famero de asistentes se encuentra dentro de un intervalo, puede hacerlo f\u00e1cilmente,<\/p>\n<p>findByNumberRange(5000, 30000);<\/p>\n<p>Aqu\u00ed, el primer argumento es el m\u00ednimo del rango y el segundo argumento es el m\u00e1ximo del rango.<\/p>\n<p>Este es el c\u00f3digo que se activa:<\/p>\n<p><code><br \/>\nNumericRangeQuery nrq = new NumericRangeQuery().min(min).max(max).field(\"attendees\");<\/code><\/p>\n<p>SearchQueryResult resultPrefix = getBucket().query(new SearchQuery(FtsConstants.FTS_IDX_CONF, nrq).fields(\"title\", \"attendees\", \"location\"));<\/p>\n<p>log.info(\"****** total aciertos :=\"+ resultadoPrefijo.aciertos().tama\u00f1o());<\/p>\n<p>for (SearchQueryRow hit : resultPrefix.hits()) {<\/p>\n<p>JsonDocument fila = bucket.get(hit.id());<\/p>\n<p>log.info(\"****** puntuaci\u00f3n := \" + hit.puntuaci\u00f3n() + \" y t\u00edtulo := \"+ fila.contenido().get(\"t\u00edtulo\") + \" asistentes := \"+ fila.contenido().get(\"asistentes\") + \" ubicaci\u00f3n := \" + fila.contenido().get(\"ubicaci\u00f3n\"));<\/p>\n<p>}<\/p>\n<p>El resultado es el siguiente: se devuelven las conferencias en las que los asistentes se encuentran dentro del intervalo indicado.<\/p>\n<p><strong>\u00a0****** total aciertos := 2<\/strong><\/p>\n<p>****** puntuaci\u00f3n := 5,513997563179222E-5 y t\u00edtulo := <strong>Asistentes a la DockerCon := 20000<\/strong>\u00a0ubicaci\u00f3n := Austin<\/p>\n<p>****** puntuaci\u00f3n := 5,513997563179222E-5 y t\u00edtulo := <strong>Asistentes a Devoxx UK := 10000<\/strong>\u00a0ubicaci\u00f3n := B\u00e9lgica<\/p>\n<h4>Consulta combinada<\/h4>\n<p>El servicio de b\u00fasqueda de texto completo de Couchbase te permite utilizar una combinaci\u00f3n de consultas seg\u00fan tus necesidades. Para demostrarlo, invoquemos primero la API proporcionando dos argumentos.<\/p>\n<p>findByMatchCombination(\"aws\", \"containers\");<\/p>\n<p>Aqu\u00ed, el c\u00f3digo del cliente est\u00e1 intentando utilizar la b\u00fasqueda combinada basada en \"aws\" y \"containers\". Veamos ahora la API de consulta.<\/p>\n<p><code><br \/>\nMatchQuery mq1 = new MatchQuery(text1).field(\"topics\");<\/code><\/p>\n<p>MatchQuery mq2 = new MatchQuery(text2).field(\"topics\");<\/p>\n<p>SearchQueryResult match1Result = getBucket().query(new SearchQuery(FtsConstants.FTS_IDX_CONF, mq1).fields(\"title\", \"attendees\", \"location\", \"topics\"));<\/p>\n<p>log.info(\"****** total de aciertos para match1 :=\"+ match1Result.hits().size());<\/p>\n<p>for (SearchQueryRow hit : match1Result.hits()) {<\/p>\n<p>JsonDocument fila = bucket.get(hit.id());<\/p>\n<p>log.info(\"****** puntuaciones de la partida 1 := \" + hit.score() + \" y t\u00edtulo := \"+ row.content().get(\"title\") + \" asistentes := \"+ row.content().get(\"attendees\") + \" temas := \" + row.content().get(\"topics\"));<\/p>\n<p>}<\/p>\n<p>SearchQueryResult match2Result = getBucket().query(new SearchQuery(FtsConstants.FTS_IDX_CONF, mq2).fields(\"title\", \"attendees\", \"location\", \"topics\"));<\/p>\n<p>log.info(\"****** total de aciertos para match2 :=\"+ match2Result.hits().size());<\/p>\n<p>for (SearchQueryRow hit : match2Result.hits()) {<\/p>\n<p>JsonDocument fila = bucket.get(hit.id());<\/p>\n<p>log.info(\"****** puntuaciones para el partido 2:= \" + hit.score() + \" y t\u00edtulo := \"+ row.content().get(\"title\") + \" asistentes := \"+ row.content().get(\"attendees\") + \" temas := \" + row.content().get(\"topics\"));<\/p>\n<p>}<\/p>\n<p>ConjunctionQuery conjunci\u00f3n = new ConjunctionQuery(mq1, mq2);<\/p>\n<p>SearchQueryResult result = getBucket().query(new SearchQuery(FtsConstants.FTS_IDX_CONF, conjunction).fields(\"title\", \"attendees\", \"location\", \"topics\"));<\/p>\n<p>log.info(\"****** total de aciertos para la consulta conjunta := \"+ result.hits().size());<\/p>\n<p>for (SearchQueryRow hit : result.hits()) {<\/p>\n<p>JsonDocument fila = bucket.get(hit.id());<\/p>\n<p>log.info(\"****** puntuaciones para la consulta conjunta:= \" + hit.score() + \" y t\u00edtulo := \"+ row.content().get(\"title\") + \" asistentes := \"+ row.content().get(\"attendees\") + \" temas := \" + row.content().get(\"topics\"));<\/p>\n<p>}<\/p>\n<p>DisjunctionQuery dis = new DisjunctionQuery(mq1, mq2);<\/p>\n<p>SearchQueryResult resultDis = getBucket().query(new SearchQuery(FtsConstants.FTS_IDX_CONF, dis).fields(\"title\", \"attendees\", \"location\", \"topics\"));<\/p>\n<p>log.info(\"****** total de aciertos para la consulta de disyunci\u00f3n :=\"+ resultDis.hits().size());<\/p>\n<p>for (SearchQueryRow hit : resultDis.hits()) {<\/p>\n<p>JsonDocument fila = bucket.get(hit.id());<\/p>\n<p>log.info(\"****** puntuaciones para la consulta disyunci\u00f3n:= \" + hit.score() + \" y t\u00edtulo := \"+ fila.contenido().get(\"t\u00edtulo\") + \" asistentes := \"+ fila.contenido().get(\"asistentes\") + \" temas := \" + fila.contenido().get(\"temas\"));<\/p>\n<p>}<\/p>\n<p>BooleanQuery bool = new BooleanQuery().must(mq1).mustNot(mq2);<\/p>\n<p>SearchQueryResult resultBool = getBucket().query(new SearchQuery(FtsConstants.FTS_IDX_CONF, bool).fields(\"title\", \"attendees\", \"location\", \"topics\"));<\/p>\n<p>log.info(\"****** total de aciertos para la consulta booelan :=\"+ resultBool.hits().size());<\/p>\n<p>for (SearchQueryRow hit : resultBool.hits()) {<\/p>\n<p>JsonDocument fila = bucket.get(hit.id());<\/p>\n<p>log.info(\"****** puntuaciones para resultBool query:= \" + hit.score() + \" y title := \"+ row.content().get(\"title\") + \" attendees := \"+ row.content().get(\"attendees\") + \" topics := \" + row.content().get(\"topics\"));<\/p>\n<p>}<\/p>\n<p>En primer lugar, se buscan coincidencias individuales a partir de los textos. Encontramos el\/los documento\/s resultante\/s que coinciden con \"aws\" como uno de los temas de la conferencia. Del mismo modo, encontramos los documentos que tienen \"contenedores\" como temas.<\/p>\n<p>A continuaci\u00f3n, empezamos a combinar los resultados individuales para formar consultas combinadas.<\/p>\n<h4>Consulta de conjunci\u00f3n<\/h4>\n<p>La consulta de conjunci\u00f3n devolver\u00eda todas las conferencias coincidentes cuyos temas fueran \"aws\" y \"containers\". Nuestro conjunto de datos actual a\u00fan no contiene ninguna conferencia de este tipo, por lo que, como era de esperar, al ejecutar la consulta no obtenemos ning\u00fan documento coincidente.<\/p>\n<p>****** total de aciertos para match1 := 1 - esto coincide con \"aws\"<\/p>\n<p>****** puntuaciones para coincidencia 1 := 0.11597946228887497 y t\u00edtulo := ReInvent asistentes := 30000 temas := [\"aws\", \"serverless\", \"microservicios\", \"cloud computing\", \"realidad aumentada\"].<\/p>\n<p>****** total de aciertos para match2 := 1 - esto coincide con \"contenedores\"<\/p>\n<p>****** puntuaciones para coincidencia 2:= 0.12527214351929328 y t\u00edtulo := DockerCon asistentes := 20000 temas := [\"contenedores\", \"devops\", \"microservicios\", \"desarrollo de productos\", \"virtualizaci\u00f3n\"].<\/p>\n<p>******<strong>\u00a0total de aciertos para la consulta conjunta := 0<\/strong><\/p>\n<h4>Consulta de disyunci\u00f3n<\/h4>\n<p>La consulta disyuntiva devolver\u00eda todas las conferencias coincidentes si alguna de las consultas candidatas devuelve una coincidencia. Dado que cada una de las consultas de coincidencia individuales devuelve una conferencia cada una, cuando ejecutamos nuestra consulta de disyunci\u00f3n, obtenemos ambos resultados.<\/p>\n<p>****** <strong>total de aciertos para la consulta disyunci\u00f3n := 2<\/strong><\/p>\n<p>****** puntuaciones para la disyunci\u00f3n query:= 0.018374455634478874 y title := DockerCon attendees := 20000 topics := [\"<strong>contenedores<\/strong>\", \"devops\", \"microservicios\", \"desarrollo de productos\", \"virtualizaci\u00f3n\"]<\/p>\n<p>****** puntuaciones para la disyunci\u00f3n query:= 0.01701143945069833 y title := ReInvent asistentes := 30000 topics := [\"<strong>aws<\/strong>\", \"sin servidor\", \"microservicios\", \"computaci\u00f3n en la nube\", \"realidad aumentada\"].<\/p>\n<h4>Consulta booleana<\/h4>\n<p>Mediante la consulta bBoolean, podemos combinar diferentes combinaciones de consultas de coincidencia. Por ejemplo, BooleanQuery bool = new BooleanQuery().must(mq1).mustNot(mq2) devuelve todas las conferencias que deben coincidir con el resultado de la consulta del primer t\u00e9rmino, que es mq1, y al mismo tiempo no deben coincidir con mq2. Puede dar la vuelta a la combinaci\u00f3n.<\/p>\n<p>El resultado de nuestro c\u00f3digo es el siguiente:<\/p>\n<p>****** <strong>total de aciertos para la consulta booelan := 1<\/strong><\/p>\n<p>****** puntuaciones para resultBool query:= 0.11597946228887497 y title := ReInvent asistentes := 30000 temas := [\"<strong>aws<\/strong>\", \"sin servidor\", \"microservicios\", \"computaci\u00f3n en la nube\", \"realidad aumentada\"].<\/p>\n<p>Devuelve la conferencia que tiene un tema llamado \"aws\" (que, por cierto, es el mismo que mq1) y no tiene un tema llamado \"containers\" (es decir, mq2). La \u00fanica conferencia que cumple estas dos condiciones se llama \"ReInvent\" y se devuelve como resultado.<\/p>\n<p>Espero que te haya resultado \u00fatil. El c\u00f3digo fuente se encuentra en <a href=\"https:\/\/github.com\/ratchakr\/fts_demo_cb\">en l\u00ednea<\/a>. Para obtener una idea general sobre el servicio de b\u00fasqueda de texto completo Couchbase, consulte lo siguiente <a href=\"https:\/\/www.couchbase.com\/blog\/es\/couchbase-4-5-developer-preview-couchbase-fts\/\">entrada del blog<\/a> para obtener informaci\u00f3n \u00fatil:<\/p>\n<p>&nbsp;<\/p>","protected":false},"excerpt":{"rendered":"<p>La b\u00fasqueda basada en texto completo es una funci\u00f3n que permite a los usuarios realizar b\u00fasquedas basadas en textos y palabras clave, y es muy popular entre los usuarios y la comunidad de desarrolladores. As\u00ed que es obvio que hay un mont\u00f3n de APIs y frameworks que ofrecen b\u00fasqueda de texto completo, incluyendo Apache Solr, Lucene y Elasticsearch, s\u00f3lo por nombrar algunos. Couchbase, uno de los principales gigantes NoSQL, comenz\u00f3 a desplegar esta caracter\u00edstica en su versi\u00f3n Couchbase Server 4.5. En este post, voy a describir c\u00f3mo integrar el servicio de b\u00fasqueda de texto completo en su aplicaci\u00f3n utilizando el Couchbase Java SDK.<\/p>","protected":false},"author":53,"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,1812],"tags":[1630],"ppma_author":[9026],"class_list":["post-2871","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-server","category-full-text-search","category-java","category-n1ql-query","tag-spring-boot"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using Couchbase FTS in Java - The Couchbase Blog<\/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\/using-couchbase-full-text-search-service-java\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using Couchbase Full Text Search Service in Java\" \/>\n<meta property=\"og:description\" content=\"Full-text based search is a feature that allows users to search based on texts and keywords, and is very popular among users and the developer community. So it\u2019s a no-brainer that there are lots of APIs and frameworks that offer full-text search, including Apache Solr, Lucene, and Elasticsearch, just to name a few. Couchbase, one of the leading NoSQL giants, started rolling out this feature in their Couchbase Server 4.5 release. In this post, I am going to describe how to integrate the full-text search service into their application using the Couchbase Java SDK.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-full-text-search-service-java\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-03-01T16:46:35+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T03:28:13+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/02\/pasted-image-0.png\" \/>\n<meta name=\"author\" content=\"Laura Czajkowski, Developer Community Manager, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Laura Czajkowski, Developer Community Manager, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/\"},\"author\":{\"name\":\"Laura Czajkowski, Developer Community Manager, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220\"},\"headline\":\"Using Couchbase Full Text Search Service in Java\",\"datePublished\":\"2017-03-01T16:46:35+00:00\",\"dateModified\":\"2025-06-14T03:28:13+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/\"},\"wordCount\":2789,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"spring-boot\"],\"articleSection\":[\"Couchbase Server\",\"Full-Text Search\",\"Java\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/\",\"name\":\"Using Couchbase FTS in Java - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2017-03-01T16:46:35+00:00\",\"dateModified\":\"2025-06-14T03:28:13+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/#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\/using-couchbase-full-text-search-service-java\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using Couchbase Full Text Search Service in Java\"}]},{\"@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\/5f1a0ece4e644bc8c037686fbc8f3220\",\"name\":\"Laura Czajkowski, Developer Community Manager, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/9deb07d5daaa00220534c31768bc4409\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g\",\"caption\":\"Laura Czajkowski, Developer Community Manager, Couchbase\"},\"description\":\"Laura Czajkowski is the Snr. Developer Community Manager at Couchbase overseeing the community. She\u2019s responsible for our monthly developer newsletter.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/es\/author\/laura-czajkowski\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Using Couchbase FTS in Java - The Couchbase Blog","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\/using-couchbase-full-text-search-service-java\/","og_locale":"es_MX","og_type":"article","og_title":"Using Couchbase Full Text Search Service in Java","og_description":"Full-text based search is a feature that allows users to search based on texts and keywords, and is very popular among users and the developer community. So it\u2019s a no-brainer that there are lots of APIs and frameworks that offer full-text search, including Apache Solr, Lucene, and Elasticsearch, just to name a few. Couchbase, one of the leading NoSQL giants, started rolling out this feature in their Couchbase Server 4.5 release. In this post, I am going to describe how to integrate the full-text search service into their application using the Couchbase Java SDK.","og_url":"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-full-text-search-service-java\/","og_site_name":"The Couchbase Blog","article_published_time":"2017-03-01T16:46:35+00:00","article_modified_time":"2025-06-14T03:28:13+00:00","og_image":[{"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/02\/pasted-image-0.png","type":"","width":"","height":""}],"author":"Laura Czajkowski, Developer Community Manager, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Laura Czajkowski, Developer Community Manager, Couchbase","Est. reading time":"14 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/"},"author":{"name":"Laura Czajkowski, Developer Community Manager, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220"},"headline":"Using Couchbase Full Text Search Service in Java","datePublished":"2017-03-01T16:46:35+00:00","dateModified":"2025-06-14T03:28:13+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/"},"wordCount":2789,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["spring-boot"],"articleSection":["Couchbase Server","Full-Text Search","Java","SQL++ \/ N1QL Query"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/","url":"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/","name":"Using Couchbase FTS in Java - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2017-03-01T16:46:35+00:00","dateModified":"2025-06-14T03:28:13+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-full-text-search-service-java\/#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\/using-couchbase-full-text-search-service-java\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Using Couchbase Full Text Search Service in Java"}]},{"@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\/5f1a0ece4e644bc8c037686fbc8f3220","name":"Laura Czajkowski, Directora de la Comunidad de Desarrolladores, Couchbase","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/9deb07d5daaa00220534c31768bc4409","url":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","caption":"Laura Czajkowski, Developer Community Manager, Couchbase"},"description":"Laura Czajkowski es la Snr. Developer Community Manager en Couchbase supervisando la comunidad. Es responsable de nuestro bolet\u00edn mensual para desarrolladores.","url":"https:\/\/www.couchbase.com\/blog\/es\/author\/laura-czajkowski\/"}]}},"authors":[{"term_id":9026,"user_id":53,"is_guest":0,"slug":"laura-czajkowski","display_name":"Laura Czajkowski, Developer Community Manager, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","author_category":"","last_name":"Czajkowski","first_name":"Laura","job_title":"","user_url":"","description":"Laura Czajkowski es la Snr. Developer Community Manager en Couchbase supervisando la comunidad. Es responsable de nuestro bolet\u00edn mensual para desarrolladores."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2871","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\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=2871"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2871\/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=2871"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=2871"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=2871"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=2871"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}