Poder ejecutar consultas de búsqueda de texto completo en Couchbase sin necesidad de herramientas adicionales como Elastic es enorme para NoSQL.
Hace aproximadamente un año, escribí sobre el uso de Búsqueda de texto completo (FTS) en Couchbase Server con el SDK de Node.js. Esto se remonta a cuando FTS estaba en la versión preliminar para desarrolladores. Aunque sigue siendo muy válido, no encierra la verdadera potencia de lo que se puede hacer con Full Text Search. Visite facetas por ejemplo. Las facetas son información agregada recogida en un conjunto de resultados y resultan útiles a la hora de categorizar los datos de los resultados.

La imagen anterior muestra una búsqueda en Amazon. Supongamos que buscamos Pokemon. Las categorías de la izquierda, como, Libros o Cine y TVpueden considerarse facetas de búsqueda.
Vamos a ver cómo aprovechar esta funcionalidad de búsqueda facetada en una aplicación Node.js.
En adelante, ya deberías tener Node.js así como Couchbase Server 5.0+ instalado y configurado. Vamos a centrarnos en el código y creación de índices para conseguir que el FTS facetado funcione en nuestra aplicación.
Preparación de un cubo de muestras con datos de muestra
En lugar de crear nuestros propios datos para trabajar con ellos, vamos a aprovechar los datos de muestra opcionales puestos a disposición de cualquiera que utilice Couchbase. Vamos a aprovechar el muestra de cerveza cubo.

Si no está seguro de cómo instalar este bucket, desde el panel de control administrativo de Couchbase, seleccione Ajustes y elija Cubos de muestra. El cubo de muestras nos dará unos ~8.000 documentos con los que trabajar.
Creación de un índice para la búsqueda de texto completo con Couchbase NoSQL
Antes de realizar cualquier búsqueda en la base de datos, debe crearse un índice FTS especial. El propósito de este índice es elegir dos propiedades en cualquier documento para buscar en ellas. Una propiedad representará lo que deseamos buscar y la otra representará nuestras facetas y lo que deseamos buscar.
En el panel de control administrativo, seleccione Buscar en y elija Añadir índice.

Aquí es donde las cosas pueden ponerse un poco extrañas si es la primera vez que juegas con la Búsqueda de Texto Completo en Couchbase.
Cuando diseñes el índice, querrás darle un nombre. Yo estoy usando el nombre búsqueda de cervezapero puede usar lo que quiera. Sólo asegúrese de que es para el correcto muestra de cerveza cubo. Deje el Identificador de tipo como predeterminado y saltar al Asignaciones de tipos sección.
Tenemos previsto buscar en documentos que tengan un tipo que coincida con cerveza de ahí el mapeo que creamos en la imagen anterior. Es importante que sólo indexemos los campos especificados a continuación, no todo el documento. En el nuevo mapeo, necesitamos crear campos hijo. Estos campos hijo representan lo que podemos facetar y lo que podemos buscar.
En descripción utilizará los valores predeterminados, pero estamos seleccionando el campo tienda opción. Esto nos permitirá acceder a ella en el resultado. La dirección categoría utilizará el campo palabra clave analizador y el tienda opción. Dado que nuestras categorías contienen varias palabras por categoría, el analizador necesita saber cómo manejar el texto delimitado por espacios. La dirección palabra clave nos permitirá trabajar con estos términos.
Por último, guarde el índice y todos los documentos deberían estar indexados al cabo de poco tiempo.
Ejecución de una consulta de búsqueda de texto completo con facetas en Node.js
Vamos a consultar este recién creado búsqueda de cerveza en dos partes para imitar cómo se haría en un sitio como Amazon. Primero vamos a ejecutar una consulta basada en un término y mostrar los resultados, así como las facetas. Estas facetas nos prepararán para la segunda parte.
Suponiendo que dispones de un proyecto Node.js correctamente configurado, añade el siguiente código JavaScript:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
const Couchbase = requiere("couchbase"); const BúsquedaQuery = Couchbase.BúsquedaQuery; const SearchFacet = Couchbase.SearchFacet; const grupo = nuevo Couchbase.Grupo("couchbase://localhost"); grupo.autentifique("demo", "123456") const cubo = grupo.openBucket("muestra de cerveza"); var tq1 = BúsquedaQuery.plazo("café").campo("descripción"); var consulta1 = BúsquedaQuery.nuevo("búsqueda de cerveza", tq1); consulta1.addFacet("categorías", SearchFacet.plazo("categoría", 5)); consulta1.límite(3); cubo.consulta(consulta1, (error, resultado, meta) => { para(var i = 0; i < resultado.longitud; i++) { consola.registro("HIT:", resultado[i].id); consola.registro("HECHOS ", meta.facetas["categorías"].términos); } }); |
La mayor parte del código anterior está relacionado con el establecimiento de una conexión con el clúster y la preparación de la búsqueda que sigue. Lo que más nos interesa es lo siguiente:
|
1 2 3 4 5 6 7 8 9 10 11 |
var tq1 = BúsquedaQuery.plazo("café").campo("descripción"); var consulta1 = BúsquedaQuery.nuevo("búsqueda de cerveza", tq1); consulta1.addFacet("categorías", SearchFacet.plazo("categoría", 5)); consulta1.límite(3); cubo.consulta(consulta1, (error, resultado, meta) => { para(var i = 0; i < resultado.longitud; i++) { consola.registro("HIT:", resultado[i].id); consola.registro("HECHOS ", meta.facetas["categorías"].términos); } }); |
En el código anterior estamos definiendo un término de búsqueda llamado tq1 que busca en el descripción propiedad para café. Cuando creamos nuestra consulta de búsqueda, definimos el índice que habíamos creado previamente y añadimos el término de búsqueda.
Añadimos una faceta denominada categoríasque es un nombre que nos acabamos de inventar. El término que categorías es el categoría dentro del documento. También estamos diciendo que no queremos que aparezcan más de cinco facetas en nuestros resultados.
Cuando ejecutemos el código, deberíamos obtener algo parecido a lo siguiente:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
HIT: lagunitas_brewing_company-cappuccino_stout DATOS: [ { plazo: Ale norteamericana, cuente: 50 }, { plazo: Cerveza irlandesa, cuente: 19 }, { plazo: Cerveza británica, cuente: 11 }, { plazo: Lager alemana, cuente: 4 }, { plazo: Ale belga y francesa, cuente: 3 } ] HIT: terrapin_beer_company-terrapin_coffee_oatmeal_imperial_stout DATOS: [ { plazo: Ale norteamericana, cuente: 50 }, { plazo: Cerveza irlandesa, cuente: 19 }, { plazo: Cerveza británica, cuente: 11 }, { plazo: Lager alemana, cuente: 4 }, { plazo: Ale belga y francesa, cuente: 3 } ] HIT: humboldt_brewing-black_xantus DATOS: [ { plazo: Ale norteamericana, cuente: 50 }, { plazo: Cerveza irlandesa, cuente: 19 }, { plazo: Cerveza británica, cuente: 11 }, { plazo: Lager alemana, cuente: 4 }, { plazo: Ale belga y francesa, cuente: 3 } ] |
Observe que se imprimen la clave del documento y las facetas que aparecen en la búsqueda. El término de las facetas también incluye cuántas veces aparecen. Si hubiéramos querido, podríamos haber incluido otros campos en el resultado, pero la clave del documento y las facetas están bien para este ejemplo.
Ahora que ya conocemos los resultados, reduzcamos nuestra búsqueda.
Realización de una consulta conjuntiva con varios términos de búsqueda en Node.js
Supongamos que nuestro usuario ha buscado cafépero también ha optado por limitar la selección de cervezas a Lager alemana. Esto significa que en algún front-end, el usuario ha seleccionado una de las facetas después de buscar.
Veamos el siguiente código JavaScript:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
const Couchbase = requiere("couchbase"); const BúsquedaQuery = Couchbase.BúsquedaQuery; const SearchFacet = Couchbase.SearchFacet; const grupo = nuevo Couchbase.Grupo("couchbase://localhost"); grupo.autentifique("demo", "123456") const cubo = grupo.openBucket("muestra de cerveza"); var tq1 = BúsquedaQuery.plazo("café").campo("descripción"); var tq2 = BúsquedaQuery.plazo("Lager alemana").campo("categoría"); var conjunción = BúsquedaQuery.conjuncts(tq1, tq2); consulta2 = BúsquedaQuery.nuevo("búsqueda de cerveza", conjunción); consulta2.addFacet("categorías", SearchFacet.plazo("categoría", 5)); consulta2.límite(3); cubo.consulta(consulta2, (error, resultado, meta) => { para(var i = 0; i < resultado.longitud; i++) { consola.registro("HIT:", resultado[i].id); consola.registro("HECHOS ", meta.facetas["categorías"].términos); } }); |
Hemos hecho algunos cambios.
En lugar de tener un único término de búsqueda, ahora tenemos dos términos de búsqueda. Uno buscará en descripcióncomo el anterior, pero el nuevo término se buscará contra el categoría propiedad. Para buscar utilizando dos términos tenemos que realizar lo que se denomina una consulta conjuntiva.
Ejecutando el código anterior se obtendría un resultado parecido al siguiente:
|
1 2 3 4 5 6 |
HIT: sprecher_brewing-black_bavarian_lager DATOS: [ { plazo: Lager alemana, cuente: 4 } ] HIT: red_oak_brewery-campo_de_batalla DATOS: [ { plazo: Lager alemana, cuente: 4 } ] HIT: four_peaks_brewing-black_betty_schwartzbier DATOS: [ { plazo: Lager alemana, cuente: 4 } ] |
Observe que nuestros resultados sólo contienen cervezas alemanas Lagers en comparación con la variedad que vimos anteriormente. Esto se debe a que hemos podido utilizar la información de las facetas para limitar nuestros resultados con una consulta secundaria.
Código JavaScript completo del ejemplo
Para verlo todo junto, tendría el siguiente aspecto:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
const Couchbase = requiere("couchbase"); const BúsquedaQuery = Couchbase.BúsquedaQuery; const SearchFacet = Couchbase.SearchFacet; const grupo = nuevo Couchbase.Grupo("couchbase://localhost"); grupo.autentifique("demo", "123456") const cubo = grupo.openBucket("muestra de cerveza"); var tq1 = BúsquedaQuery.plazo("café").campo("descripción"); var consulta1 = BúsquedaQuery.nuevo("búsqueda de cerveza", tq1); consulta1.addFacet("categorías", SearchFacet.plazo("categoría", 5)); consulta1.límite(3); cubo.consulta(consulta1, (error, resultado, meta) => { para(var i = 0; i < resultado.longitud; i++) { consola.registro("HIT:", resultado[i].id); consola.registro("HECHOS ", meta.facetas["categorías"].términos); } }); var tq2 = BúsquedaQuery.plazo("Lager alemana").campo("categoría"); var conjunción = BúsquedaQuery.conjuncts(tq1, tq2); consulta2 = BúsquedaQuery.nuevo("búsqueda de cerveza", conjunción); consulta2.addFacet("categorías", SearchFacet.plazo("categoría", 5)); consulta2.límite(3); cubo.consulta(consulta2, (error, resultado, meta) => { para(var i = 0; i < resultado.longitud; i++) { consola.registro("HIT:", resultado[i].id); consola.registro("HECHOS ", meta.facetas["categorías"].términos); } }); |
Tenga en cuenta que el código anterior no es realista. Por un lado, es asíncrono. La realidad de las cosas sería controlada por la interacción del usuario. El usuario realiza una búsqueda, altera algo, luego realiza una búsqueda secundaria como se describió anteriormente.
Conclusión
Acaba de ver cómo buscar con facetas en Couchbase utilizando Full Text Search (FTS) y el SDK de Node.js. FTS es una forma de consultar el lenguaje natural y es muy diferente de N1QL. FTS es muy potente y se pueden hacer muchas cosas geniales.
Para obtener más información sobre el uso de la búsqueda de texto completo con Couchbase, consulte la página Portal para desarrolladores de Couchbase.