Una de las principales características introducidas en Couchbase Lite 2.0es la nueva interfaz de consulta basada en N1QLel lenguaje de consulta declarativo de Couchbase que extiende SQL para JSON. Si estás familiarizado con SQL, te sentirás como en casa con la semántica de la nueva API. Cubrimos los fundamentos de la interfaz en un anterior entrada del blog. Las matrices son un componente integral del modelado de datos con JSON. En esta entrada del blog, hablaremos de la consulta de colecciones de matrices mediante la nueva API.
En este blog se da por sentado que usted conoce los fundamentos, así que si aún no lo ha hecho, asegúrese de revisar la página entrada anterior primero. La última sección de la entrada contiene enlaces a otros blogs de consulta relevantes.
Fondo
Si estabas usando versiones 1.x de Couchbase Mobile, probablemente estés familiarizado con Map-Views para crear índices y consultas. En la versión 2.0, ya no es necesario crear vistas y funciones de mapa. En su lugar, una sencilla interfaz le permite crear índices y puede utilizar una interfaz Query Builder para construir sus consultas. En comparación, la nueva interfaz de consulta es más sencilla de utilizar y mucho más potente. Descubriremos algunas de sus características en este post.
Ejemplo de proyecto
Aunque los ejemplos que aquí se comentan utilizan Swift para iOS, ten en cuenta que, salvo algunas pequeñas diferencias, la misma interfaz de consulta también es compatible con las plataformas Android y Windows. Por lo tanto, con algunos ajustes menores, deberías poder reutilizar los ejemplos de consulta de este artículo cuando trabajes con otras plataformas.
Siga las instrucciones siguientes si está interesado en un proyecto Swift de muestra
- Clonar el iOS Swift Playground desde GitHub
1 |
$ git clonar https://github.com/couchbaselabs/couchbase-lite-ios-api-playground |
- Siga las instrucciones de instalación en el LÉAME para construir y ejecutar la zona de juegos.
Modelo de datos de muestra
Utilizaremos la base de datos de muestras de viajes aquí
El conjunto de datos de la muestra incluye varios tipos de documentos identificados por el tipo
del documento. Nos centraremos en documentos de tipo
"hotel" . A continuación se muestra el modelo de documento JSON. Por brevedad, hemos omitido algunas de las propiedades del modelo a continuación.
En concreto, obsérvese que el modelo incluye colecciones anidadas - me gusta_público
y reseñas
. Las consultas de las secciones siguientes tratarán de estas colecciones anidadas.
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 34 35 36 37 38 39 40 41 42 |
{ "tipo": "hotel", "nombre": "Albergue Juvenil Medway", "dirección": "Capstone Road, ME7 3JE", "ciudad": "Medway", "país": "Reino Unido", "descripción": "bla bla", "public_likes": [ "Julius Tromp I", "Corrine Hilll" ], "revisiones": [ { "autor": "Ozella Sipes", "contenido": "bla bla"., "fecha": "2013-06-22 18:33:50 +0300", "ratings": { "Limpieza": 5, "Localización": 4, "En general": 4, "Habitaciones": 3, "Servicio": 5, "Valor": 4 } }, { "autor": "Jeremy Snapes", "contenido": "bla bla"., "fecha": "2013-05-05 18:33:50 +0300", "ratings": { "Limpieza": 2, "Localización": 2, "En general": 4, "Habitaciones": 3, "Servicio": 5, "Valor": 4 } } ], "url":"http://www.yha.org.uk", "vacante": verdadero } |
** Consulte el modelo anterior para cada uno de los ejemplos de consulta a continuación. **
El asa de la base de datos
En las consultas siguientes, utilizaremos la función Base de datos
API para abrir/crear Base de Datos CouchbaseLite.
1 2 |
var opciones = Configuración de la base de datos() deje db = pruebe Base de datos(nombre: kDBName, config: opciones) |
Índices
Para acelerar las consultas de lectura, puede crear índices sobre las propiedades que va a consultar. La mejora del rendimiento sería significativa en grandes conjuntos de datos. Por supuesto, tenga en cuenta que habrá un aumento en las necesidades de almacenamiento para almacenar los índices y el rendimiento de las escrituras también puede verse afectado. Por lo tanto, tenga cuidado al crear demasiados índices.
El siguiente ejemplo crea un ÍndiceValor
en el tipo
de un documento
1 |
pruebe db.createIndex(IndexBuilder.valueIndex(artículos: ValueIndexItem.propiedad("tipo")),withName: "typeIndex") |
El siguiente ejemplo crea un ÍndiceValor
en tipo
y nombre
propiedades de un Documento
1 |
pruebe db.createIndex(IndexBuilder.valueIndex(artículos: ValueIndexItem.propiedad("tipo"),ValueIndexItem.propiedad("nombre")),withName: "TypeNameIndex") |
Contención de matrices
La siguiente consulta recupera los ids, nombres y me gusta_público propiedades de los documentos en los que me gusta_público
en "hotel" tipo
contiene el valor de "Corrine Hilll". Para ello, el **ArrayFunction.contains**
se utiliza en la función me gusta_público
matriz.
1 2 3 4 5 6 |
deje searchQuery = ConsultaBuilde.seleccione(SeleccionarResultado.expresión(Meta.id), SeleccionarResultado.expresión(Expresión.propiedad("nombre")), SeleccionarResultado.expresión(Expresión.propiedad("public_likes"))) .de(Fuente de datos.base de datos(db)) .donde(Expresión.propiedad("tipo").equalTo(Expresión.cadena("hotel")) .y( ArrayFunction.contiene(Expresión.propiedad("public_likes"), valor: Expresión.cadena("Corrine Hilll")))) |
Tamaño de la matriz
La siguiente consulta recupera los ids, nombres y las propiedades talla de me gusta_público en "hotel" tipo
documentos. Para ello, el **ArrayFunction.length**
se utiliza en la función me gusta_público
para obtener el tamaño de la matriz.
Además, observe que estamos utilizando como
expresión a alias el valor del recuento del array a NumLikes. Habíamos introducido alias en la entrada anterior del blog sobre Fundamentos de la consulta. Si no se asigna un alias al resultado de la consulta arrayLength
la clave de la propiedad sería $1
lo cual no es muy intuitivo.
1 2 3 4 5 6 |
deje searchQuery = Constructor de consultas.seleccione(SeleccionarResultado.expresión(Meta.id), SeleccionarResultado.expresión(Expresión.propiedad("nombre")), SeleccionarResultado.expresión(ArrayFunction.longitud(Expresión.propiedad("public_likes"))).como("NumLikes")) .de(Fuente de datos.base de datos(db)) .donde(Expresión.propiedad("tipo").equalTo(Expresión.cadena("hotel"))) .límite(Expresión.int(límite)) |
Evaluación de los miembros de la matriz
Mientras que el ArrayFunction.contains
le permite comprobar si la matriz dada contiene un valor específico, la función en
se puede utilizar para evaluar uno o todos los miembros de una matriz en función de un criterio especificado por la variable satisface
expresión. Se trata de una potente función de filtrado de documentos.
Enen
se utiliza con la expresión cualquier
, cada
o el anyAndEvery
operadores cuantificados en ArrayExpression
para evaluar cualquier, todos o cualquier/todos los elementos del objeto array.
La siguiente consulta devuelve los documentos en los que cualquier
de los valores del me gusta_público
comienza con los caracteres "Corr".
1 2 3 4 5 6 7 8 9 10 11 |
//1. deje VAR_LIKEDBY = ArrayExpression.variable("likedby") //2. deje searchQuery = Constructor de consultas.seleccione(SeleccionarResultado.expresión(Meta.id), SeleccionarResultado.expresión((Expresión.propiedad("public_likes")))) .de(Fuente de datos.base de datos(db)) .donde(Expresión.propiedad("tipo").equalTo(Expresión.cadena("hotel")) .y(ArrayExpression.cualquier(VAR_LIKEDBY).en(Expresión.propiedad("public_likes")) .satisface(VAR_LIKEDBY.como(Expresión.cadena("Cor%"))))) .límite(Expresión.int(límite))<código> |
-
- Declara una variable con el nombre "likedby" para representar cada elemento en el
me gusta_público
matriz - En
cualquier
ArrayExpression comprueba si el elemento del array representado por la variableme gustaen
cumple los criterios de lacomo
expresión. El sitiocomo
comprueba si el valor del elemento representado por la variable "likedby" empieza por "Cor".
- Declara una variable con el nombre "likedby" para representar cada elemento en el
Indexación de matrices
También puede consultar elementos en índices específicos. La siguiente consulta devuelve el índice nombre
y primer miembro de la me gusta_público
matriz de propiedades de todos los documentos "hotel
1 2 3 4 5 6 |
deje searchQuery = Constructor de consultas.seleccione(SeleccionarResultado.expresión(Meta.id), SeleccionarResultado.expresión(Expresión.propiedad("nombre")), SeleccionarResultado.expresión(Expresión.propiedad("public_likes[0]"))) .de(Fuente de datos.base de datos(db)) .donde(Expresión.propiedad("tipo").equalTo(Expresión.cadena("hotel"))) .límite(Expresión.int(límite)) |
Evaluación de matrices anidadas
Puede evaluar los miembros de un array anidado. Para ello, puede aplicar un ruta de acceso
a la expresión de la variable. La matriz anidada debe tener un nivel de profundidad.
La siguiente consulta devuelve los documentos en los que cualquier
de los valores anidados clasificaciones
tiene el valor En general
calificación de la propiedad superior o igual a 4.
Como habrá observado en el modelo de datos anterior, la propiedad "reviews" contiene una matriz de objetos. Cada uno de los objetos contiene un clasificaciones
que a su vez contiene la matriz En general
propiedad.
1 2 3 4 5 6 7 8 9 10 11 12 |
// 1. deje VAR_OVERALL = ArrayExpression.variable("review.ratings.Overall") //2. deje VAR_REVISIONES = ArrayExpression.variable("revisión") //3. deje searchQuery = Constructor de consultas.seleccione(SeleccionarResultado.expresión(Meta.id), SeleccionarResultado.expresión(Expresión.propiedad("nombre"))) .de(Fuente de datos.base de datos(db)) .donde(Expresión.propiedad("tipo").equalTo(Expresión.cadena("hotel")) .y(ArrayExpression.cualquier(VAR_REVISIONES).en(Expresión.propiedad("revisiones")) .satisface(VAR_OVERALL.greaterThanOrEqualTo(Expresión.int(4))))) .límite(Expresión.int(límite)) |
- Declarar una variable para representar un elemento del
review.ratings.Overall
matriz - Declarar una variable para representar cada elemento del
reseñas
matriz - En
cualquier
comprueba si el elemento de la matriz representado porrevise
cumple los criterios de lacomparación
expresión. El sitiocomparación
comprueba el valor deEn general
propiedad delclasificaciones
en el objeto representado por la variable "review" es mayor o igual que 4.
Limitaciones
Las capacidades de manipulación de matrices no son tan amplias como las de N1QL conjunto de características. Pero es un buen punto de partida. Estas capacidades pueden estar disponibles en futuras versiones de Couchbase Mobile.
Así que, por ahora, depende de la aplicación manipular los resultados del array utilizando las capacidades de procesamiento de colecciones del lenguaje.
Veamos este ejemplo en swift
- Refiriéndonos al modelo de datos, digamos que desea determinar el mínimo
Limpieza
para un hotel determinado en función de las opiniones sobre el mismo.
Del modelo anterior , obsérvese que el Limpieza
es un miembro de la propiedad clasificaciones
contenida en cada objeto miembro de reseñas
matriz.

Para ello, puede realizar una consulta a Couchbase Lite para obtener el archivo reseñas
para un hotel con Id especificado de la siguiente manera -
1 2 3 4 5 6 |
// 1. Consulta de la matriz de propiedades de reseñas para el hotel dado deje searchQuery = Constructor de consultas.seleccione( SeleccionarResultado.expresión(Expresión.propiedad("revisiones"))) .de(Fuente de datos.base de datos(db)) .donde(Expresión.propiedad("tipo").equalTo(Expresión.cadena("hotel")) .y(Meta.id.equalTo(Expresión.cadena("hotel_10025")))) |
En resultSet
La respuesta a la consulta anterior sería un array con un único elemento. Este elemento correspondería al documento "hotel" para el Id especificado.
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 |
[ { "revisiones": [ { "autor": "Ozella Sipes", "contenido": "blah", "fecha": "2013-06-22 18:33:50 +0300", "ratings": { "Limpieza": 5, "Localización": 4, "En general": 4, "Habitaciones": 3, "Servicio": 5, "Valor": 4 } }, { "autor": "fuzzy Snipes", "contenido": "blah", "fecha": "2013-06-22 18:33:50 +0300", "ratings": { "Limpieza": 2, "Localización": 3, "En general": 4, "Habitaciones": 3, "Servicio": 5, "Valor": 4 } } ] } ] |
Ahora, la aplicación tiene que implementar la lógica para iterar sobre los archivos reseñas
y, para cada miembro de la matriz, obtener el archivo clasificaciones
y la propiedad Limpieza
valor.
He aquí una posible forma de hacerlo en swift.
- Primero, iteramos sobre el resultSet y extraemos el valor de la propiedad "reviews".
1 2 3 4 5 6 7 8 |
var coincide con:[[Cadena:Cualquier]] = [[Cadena:Cualquier]]() do { para fila en pruebe searchQuery.ejecutar() { si deje reviewData = fila.matriz(forKey: "revisiones")?.toArray() como? [[Cadena:Cualquier]] { coincide con.añadir(reviewData) } } } |
Tras el procesamiento del bucle, la matriz "matches" sería algo parecido a lo que se muestra a continuación. Sería un array que contendría el array anidado correspondiente a las reseñas -
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 |
[ [ { "autor": "Ozella Sipes", "contenido": "blah", "fecha": "2013-06-22 18:33:50 +0300", "ratings": { "Limpieza": 5, "Localización": 4, "En general": 4, "Habitaciones": 3, "Servicio": 5, "Valor": 4 } }, { "autor": "fuzzy Snipes", "contenido": "blah", "fecha": "2013-06-22 18:33:50 +0300", "ratings": { "Limpieza": 2, "Localización": 3, "En general": 4, "Habitaciones": 3, "Servicio": 5, "Valor": 4 } } ] ] |
- A continuación, puede utilizar funciones del lenguaje swift como
flatMap
ymapa
procesar la matriz resultante para obtener la calificación mínima de "Limpieza" de un hotel determinado
1 2 3 4 5 6 |
deje minCleanlinessValue = coincide con.flatMap{$0} .mapa{devolver ($0["ratings"] como? [Cadena:Cualquier])?["Limpieza"] como? Int} .flatMap{$0} .min { (a, b) -> Bool en devolver a < b } |
Se haría algo similar en lenguajes que soportan construcciones funcionales como mapa plano
y mapa
.
¿Qué sigue?
En esta entrada de blog vimos cómo puedes manejar tipos de colección Array usando el nuevo Query API en Couchbase Mobile 2.0. Esto es un comienzo. Espera ver más funcionalidades en futuras versiones. Puedes descargar la versión preliminar de nuestro descargas página.
Aquí hay otros posts relacionados con Couchbase Mobile Query que pueden ser de interés
- Este entrada del blog analiza los fundamentos de la API de consulta
- Este entrada del blog analiza las funciones de búsqueda de texto completo.
- Este entrada del blog explica cómo realizar consultas JOIN
Si tiene alguna pregunta o sugerencia, deje un comentario a continuación o póngase en contacto conmigo en Twitter @rajagp o envíeme un correo electrónico priya.rajagopal@couchbase.com. En Foros de Couchbase son otro buen lugar para plantear preguntas.