La versión 2.0 de Couchbase Lite, trae una plétora de nuevas funciones y mejoras. Ya hablamos de una de estas mejoras, a saber, el nuevo protocolo de replicación entre en un anterior entrada en el blog sobre Replicación 2.0. En esta entrada de blog, le presentaremos otra característica importante: la interfaz de consulta de Couchbase Lite. La nueva interfaz de consulta se basa 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.
Esta entrada presenta la interfaz de consulta y cubre los aspectos básicos. Consulte la última sección de esta entrada para obtener información específica sobre otras entradas de blog relacionadas con funciones de consulta más avanzadas.
Puede descargar las versiones preliminares de Couchbase Mobile 2.0 desde nuestra página web descargas página.
Fondo
Si utilizabas las versiones 1.x de Couchbase Mobile, probablemente estés familiarizado 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 exponen utilizan Swift para iOS, ten en cuenta que, salvo algunas pequeñas diferencias, la misma interfaz de consulta es compatible también con las plataformas Android y Windows. Por lo tanto, con algunos ajustes menores, deberías poder reutilizar los ejemplos 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 clone 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" y "hito". A continuación se muestra el modelo de documento JSON. Para simplificar, hemos omitido algunas de las propiedades del modelo a continuación.

Conceptos básicos
Abrir / Crear una base de datos
Para todas las consultas que se realizan a continuación, utilizaremos la función Base de datos API para abrir/crear Base de Datos CouchbaseLite.
|
1 2 |
var options = DatabaseConfiguration() let db = try Database(name: kDBName, config: options) |
Í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 |
try db.createIndex(IndexBuilder.valueIndex(items: ValueIndexItem.property("type")),withName: "typeIndex") |
El siguiente ejemplo crea un ÍndiceValor en tipo y nombre propiedades de un Documento
|
1 |
try db.createIndex(IndexBuilder.valueIndex(items: ValueIndexItem.property("type"),ValueIndexItem.property("name")),withName: "TypeNameIndex") |
Obtención de documentos de la base de datos
Una consulta en Couchbase Lite se construye usando la API del constructor de consultas.
La siguiente consulta obtiene todos los documentos de la base de datos especificada. Para cada documento que coincida con la consulta, se obtienen todas las propiedades asociadas al documento.
|
1 2 3 |
let searchQuery = QueryBuilder .select(SelectResult.all()) .from(DataSource.database(db)) |
Obtención de documentos de la base de datos con paginación
Esta es la estructura de una consulta simple que obtiene límite número de documentos de la base de datos a partir del offset. Para cada documento que coincide con la consulta, se obtienen todas las propiedades asociadas al documento.
|
1 2 3 4 |
let searchQuery = QueryBuilder .select(SelectResult.all()) .from(DataSource.database(db)) .limit(Expression.int(limit),offset: Expression.int(offset)) |
Valores de retorno con SelectResult
A SeleccionarResultado representa un único valor de retorno de la consulta. Los documentos en Couchbase Lite comprenden las propiedades del documento especificadas como un diccionario de pares clave-valor y metadatos asociados. Los metadatos consisten en el Id del documento y el Id de la secuencia asociada con el Documento. Cuando se consulta un documento, los metadatos del documento no se devuelven por defecto. Deberá solicitar explícitamente los metadatos.
SelectResult.all()- Devuelve todas las propiedades asociadas a un Documento
SeleccionarResultado(Expresión)- Devuelve las propiedades de un Documento en función del
Expresión. Más adelante hablaremos de los distintos tipos de expresiones.
- Devuelve las propiedades de un Documento en función del
SelectResult.expression(Expresión.Meta.id)- Devuelve el Id del documento
SelectResult.expression(Expression.Meta.sequence)- Devuelve el Id de secuencia (utilizado en las réplicas)
Puede especificar una lista separada por comas de SeleccionarResultado expresiones en el seleccione de su consulta.
Por ejemplo, la siguiente sentencia select busca el Id del documento así como el tipo y nombre propiedades del documento
|
1 2 3 |
select(SelectResult.expression(Expression.Meta.id), SelectResult.expression(Expression.property("type")), SelectResult.expression(Expression.property("name"))) |
Expresión de consulta
Una expresión de consulta se utiliza para construir una sentencia de consulta
Couchbase Lite incluye soporte para Expresión Tipos.
- Propiedad
- Agregado
- Cadena
- Intercalación
- Regex
- FTS
- Operador de comprobación nula
- Expresiones aritméticas
- Metadatos
- Coincidencia de patrones
- Comparación
- Colección
- Función
- Parámetro
- Cuantificado
- Operador Bitwise
Tratamiento de las respuestas a las consultas
El resultado de la ejecución de la consulta es un array en el que cada miembro del array es un Diccionario / Mapa correspondiente a un documento que satisface la consulta.
|
1 2 3 |
select(SelectResult.expression(Expression.Meta.id), SelectResult.expression(Expression.property("type")), SelectResult.expression(Expression.property("name"))) |
- Si consulta todas las propiedades del documento mediante
SelectResult.all()cada miembro de la matriz de respuesta es un par clave-valor, en el que el nombre de la base de datos es la clave y el diccionario correspondiente al documento es el valor de la clave.
|
1 2 3 4 |
let searchQuery = QueryBuilder .select(SelectResult.all()) .from(DataSource.database(db)) .limit(Expression.int(limit),offset: Expression.int(offset)) |
- Los resultados serían algo parecido a esto (donde "muestra-viaje" es el nombre de la base de datos )
12345678910111213141516171819202122232425[{"travel-sample": {"callsign": "MILE-AIR","country": "United States","iata": "Q5","icao": "MLA","id": 10,"name": "40-Mile Air","type": "airline"}},{"travel-sample": {"callsign": "TXW","country": "United States","iata": "TQ","icao": "TXW","id": 10123,"name": "Texas Wings","type": "airline"}}]
El siguiente fragmento de código es un ejemplo (en Swift) de cómo procesar los resultados anteriores para obtener los detalles del objeto documento
12345678for row in try searchQuery.execute() {if let dict = row.toDictionary() as? [String:Any],let docObject = dict["travel-sample"] as? [String:Any] {// You can now process the document propertieslet name = docObject["name"]let type = docObject["type"]}}
- Si consulta el Id del documento mediante
SelectResult.expression(Expresión.Meta.id)entonces cada miembro de la matriz de respuesta es un par clave-valor, con"id"como clave y el Id del documento como valor.
Por ejemplo, considere la consulta
|
1 2 3 4 |
let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id)) .from(DataSource.database(db)) .limit(Expression.int(limit)) |
- Los resultados serían algo así -
1234567891011[{"id": "airline_112"},{"id": "airline_189"},{"id": "airline_1209"}]
El siguiente fragmento de código es un ejemplo (en Swift) de cómo procesar los resultados anteriores para obtener los detalles del objeto documento utilizando el Id del documento
1234567for row in try searchQuery.execute() {if let dict = row.toDictionary() as? [String:Any],let docId = dict["id"] as? String {// You can now fetch the details of the document using the Idlet doc = try db.getDocument(docId)}} - Si está consultando una propiedad o propiedades específicas del documento utilizando, por ejemplo,
SelectResult.expression(Expression.property("tipo")cada miembro de la matriz de respuesta es un par clave-valor, con el nombre de la propiedad o propiedades como clave(s) y los valores de propiedad correspondientes como valorPor ejemplo, considere la consulta
|
1 2 3 4 |
let searchQuery = QueryBuilder .select(SelectResult.expression(Expression.property("type"))) .from(DataSource.database(db)) .limit(Expression.int(limit)) |
- Los resultados serían algo así -
1234567891011[{"type": "airline"},{"type": "airline"},{"type": "hotel"}]
El siguiente fragmento de código es un ejemplo (en Swift) de cómo procesar los resultados anteriores para obtener los valores de las propiedades que ha consultado
123456for row in try searchQuery.execute() {if let docObject = row.toDictionary() as? [String:Any] {// You can now fetch the details of the document using the property name as keylet type = docObject["type"]}}
Puede consultar los metadatos y las propiedades del documento al mismo tiempo utilizando una lista separada por comas de los siguientes elementosSeleccionarResultadocada miembro de la matriz de respuesta es un par clave-valor, tal como se ha explicado anteriormente.
12345let searchQuery = QueryBuilder.select(SelectResult.expression(Meta.id),SelectResult.expression(Expression.property("type"))).from(DataSource.database(db)).limit(Expression.int(limit))
Los resultados serían algo así -
123456789101112131415[{"id":"airline_1001","type": "airline"},{"id":"airline_900","type": "airline"},{"id":"hotel_1001","type": "hotel"}]
El siguiente fragmento de código es un ejemplo (en Swift) de cómo procesar los resultados anteriores para obtener los valores de las propiedades que ha consultado
1234567for row in try searchQuery.execute() {if let docObject = row.toDictionary() as? [String:Any] {// You can now fetch the details of the document using the property name as keylet type = docObject["type"]let docId = docObject["id"]}}
Introducción de la cláusula Where
De forma similar a SQL, puede utilizar la función donde para filtrar los documentos que se devolverán como parte de la consulta. En seleccione recibe un Expresión. Puede encadenar cualquier número de Expresiones para implementar sofisticadas capacidades de filtrado.
Filtrado de documentos en función de una propiedad específica
En el ejemplo siguiente, utilizamos Expresión de propiedad junto con Expresiones de comparación para filtrar documentos en función de una propiedad específica del documento. En el siguiente ejemplo se muestra la función equalTo expresión de comparación.
Nota: Cuando se hace referencia a una propiedad en un archivo Expresión de propiedadpodemos utilizar rutas clave (en notación de puntos) para especificar la ruta a una propiedad anidada.
|
1 2 3 4 5 |
let searchQuery = QueryBuilder .select(SelectResult.all()) .from(DataSource.database(db)) .where(Expression.property("type").equalTo(Expression.string("hotel"))) .limit(Expression.int(limit)) |
La lista de operadores de comparación admitidos incluye
* lessThan
* notLessThan
* lessThanOrEqualTo
* notLessThanOrEqualTo
* mayorQue
* notGreaterThan
* Mayor que o igual a
* notGreaterThanOrEqualTo
* equalTo
* notEqualTo
Filtrado de documentos mediante expresiones lógicas
Podemos utilizar Expresión lógica encadenar varios expresiones de comparación. En el ejemplo siguiente, obtenemos documentos de tipo hotel cuyo país es igual a "Estados Unidos" o "Francia y cuyo vacante propiedad es verdadero. En otras palabras, buscamos todos los hoteles de Estados Unidos o Francia que tienen una plaza libre.
|
1 2 3 4 5 6 7 8 |
let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id)) .from(DataSource.database(db)) .where(Expression.property("type").equalTo(Expression.string("hotel")) .and(Expression.property("country").equalTo(Expression.string ("United States")) .or(Expression.property("country").equalTo(Expression.string ("France")))) .and(Expression.property("vacancy").equalTo(Expression.boolean(true)))) .limit(Expression.int(limit)) |
Coincidencia de patrones
En como y regex pueden utilizarse para la concordancia de cadenas. Éstas realizan **comparaciones que distinguen mayúsculas y minúsculas**. Por lo tanto, si desea que la coincidencia de cadenas no distinga entre mayúsculas y minúsculas, deberá utilizar Función.inferior o Función.superior para transformar la cadena coincidente a sus equivalentes en minúsculas o mayúsculas.
Coincidencia exacta
En el ejemplo siguiente, buscamos documentos de tipo "hito" donde el nombre coincide exactamente con la cadena "Museo de los Ingenieros Reales". Tenga en cuenta que como distingue entre mayúsculas y minúsculas, utilizamos Función.inferior para transformar la cadena coincidente en su equivalente en minúsculas. Así, la siguiente consulta devolverá "hito" tipo documentos con nombre a juego "Museo de los Ingenieros Reales", "museo real de ingenieros", "MUSEO REAL DE INGENIEROS" etc.
|
1 2 3 4 5 6 7 8 |
let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property("country")), SelectResult.expression(Expression.property("name"))) .from(DataSource.database(db)) .where(Expression.property("type").equalTo(Expression.string("landmark")) .and(Function.lower(Expression.property("name")).like(Expression.string("royal engineers museum")))) .limit(Expression.int(limit)) |
Partido Wildcard
Podemos utilizar % signo dentro de un como para hacer una coincidencia comodín con cero o más caracteres. El uso de comodines le permite tener cierta imprecisión en su cadena de búsqueda.
En el ejemplo siguiente, buscamos documentos de tipo "hito" donde el nombre coincide con cualquier cadena que empiece por "eng" seguida de cero o más caracteres, la letra "e", seguida de cero o más caracteres. Una vez más, estamos utilizando Función.inferior para que el caso de búsqueda sea insensible.
La siguiente consulta devolverá "hito" tipo documentos con nombre a juego "Ingenieros", "motor", "huevo inglés" , "Águila de Inglaterra" etc. Observe que las coincidencias pueden abarcar límites de palabras.
|
1 2 3 4 5 6 7 8 |
let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property("country")), SelectResult.expression(Expression.property("name"))) .from(DataSource.database(db)) .where(Expression.property("type").equalTo(Expression.string("landmark")) .and( Function.lower(Expression.property("name")).like(Expression.string("%eng%r%")))) .limit(Expression.int(limit)) |
Coincidencia de caracteres comodín
Podemos utilizar "_" signo dentro de un como para realizar una coincidencia comodín con un único carácter.
En el ejemplo siguiente, buscamos documentos de tipo "hito" donde el nombre coincide con cualquier cadena que empiece por "eng" seguida de exactamente 4 caracteres comodín y termine en la letra "r".
Observe que, a diferencia de los ejemplos anteriores, no estamos utilizando Función.inferior para transformar la cadena de búsqueda a minúsculas. Así, la búsqueda distinguirá entre mayúsculas y minúsculas.
La siguiente consulta devolverá "hito" tipo documentos con nombre a juego "Ingeniero", "Ingeniero1" etc.
|
1 2 3 4 5 6 7 8 9 |
let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property("country")), SelectResult.expression(Expression.property("name"))) .from(DataSource.database(db)) .where(Expression.property("type").equalTo(Expression.string("landmark")) .and( Expression.property("name") .like(Expression.string("%Eng____r%")))) .limit(Expression.int(limit)) |
Coincidencia Regex
En regex puede utilizarse para coincidencias que distingan entre mayúsculas y minúsculas. Similar al comodín como expresiones, regex La concordancia de patrones basada en expresiones le permite tener cierta imprecisión en su cadena de búsqueda.
En el ejemplo siguiente, buscamos documentos de tipo "hito" donde el nombre coincide con cualquier cadena (en los límites de las palabras) que empiece por "eng" seguida de exactamente 4 caracteres comodín y acabe en la letra "r". Una vez más, estamos utilizando Función.inferior para que el caso de búsqueda sea insensible.
La siguiente consulta devolverá "hito" tipo documentos con nombre a juego "Motor", "motor" etc. Tenga en cuenta que el \b especifica que la coincidencia debe producirse en los límites de palabra.
|
1 2 3 4 5 6 7 |
let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property("name")) ) .from(DataSource.database(db)) .where(Expression.property("type").equalTo(Expression.string("landmark")) .and(Function.lower(Expression.property("name")).regex(Expression.string("\\beng.*r.*\\b")))) .limit(Expression.int(limit)) |
Documentos con propiedad nula o ausente
Una de las características del lenguaje de consulta que lo diferencia de SQL es la posibilidad de consultar documentos con propiedades nulas o ausentes.
En isNullOrMissing() se utiliza junto con la expresión Expresión de propiedad para comprobar si la propiedad especificada tiene un valor nulo o ausente. La dirección isNullOrMissing() hace lo contrario.
En el ejemplo siguiente, buscamos todos los documentos en los que el campo correo electrónico nula o ausente.
|
1 2 3 4 5 6 |
let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property("email"))) .from(DataSource.database(db)) .where(Expression.property("email").isNullOrMissing()) .limit(Expression.int(limit)) |
Ordenación de documentos
Es posible ordenar los resultados de una consulta en función del resultado de una expresión determinada.
El siguiente ejemplo devuelve documentos de tipo igual a "hotel" ordenados en orden ascendente por el valor de la variable título propiedad.
|
1 2 3 4 5 6 7 |
let searchQuery = QueryBuilder.select( SelectResult.expression(Meta.id), SelectResult.expression(Expression.property("title"))) .from(DataSource.database(db)) .where(Expression.property("type").equalTo(Expression.string("hotel"))) .orderBy(Ordering.property("title").ascending()) .limit(Expression.int(limit)) |
Manipulación de cadenas
Las capacidades de manipulación de cadenas son integrales para cualquier procesamiento de datos. En ejemplos anteriores, vimos cómo el Función.inferior se puede utilizar para transformar una cadena a minúsculas equivalentes para realizar comparaciones de cadenas sin distinción entre mayúsculas y minúsculas.
Couchbase Lite soporta las siguientes funciones de procesamiento de cadenas.
|
1 2 3 4 5 6 7 8 |
- Function.lower(String Expression) - Function.ltrim(String Expression) - Function.rtrim(String Expression) - Function.trim(String Expression) - Function.upper(String Expression) - Function.length(String Expression) - Function.substring(String Expression, String Expression) |
El ejemplo siguiente devuelve los documentos de correo electrónico contiene la subcadena "natgeo.org". En nombre se convierte a mayúsculas en la respuesta.
|
1 2 3 4 5 6 |
let searchQuery = QueryBuilder.select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property("email")), SelectResult.expression(Expression.property("name"))) .from(DataSource.database(db)) .where(Function.contains(Expression.property("email"), substring: Expression.string ("natgeo.org"))) .limit(Expression.int(limit)) |
Intercalación
Las funciones de intercalación mejoran las capacidades de comparación y ordenación de cadenas, ya que admiten cadenas unicode, manipulación de cadenas en función de la configuración regional y funciones específicas de cada idioma, como los diacríticos. Puede obtener más información sobre la intercalación en redacción por Jens Alfke.
El ejemplo siguiente define las reglas de intercalación para que se ignoren las mayúsculas y los acentos. Este intercalador se aplica a la función de comparación de cadenas en el campo nombre propiedad. Los resultados incluirán documentos en los que nombre es igual a cadenas como "Hotel Novotel Paris La Defense" , "Hotel Novotel Paris La Défense", etc.
|
1 2 3 4 5 6 7 8 9 10 |
let collator = Collation.unicode() .ignoreAccents(true) .ignoreCase(true) let searchQuery = QueryBuilder.select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property("name"))) .from(DataSource.database(db)) .where(Expression.property("type").equalTo(Expression.string("hotel")) .and(Expression.property("name").collate(collator).equalTo(Expression.string ("Hotel novotel paris la defense")))) .limit(Expression.int(limit)) |
Existen algunas limitaciones en el soporte de la Cotejo - en el momento de escribir este post, no se puede utilizar con consultas de concordancia de patrones tales como como y regex .
Parametrización
Una de las características más potentes de la interfaz de consulta es la posibilidad de establecer parámetros en una consulta. Esto le da la flexibilidad de actualizar los valores de los parámetros de una consulta en cualquier momento sin tener que volver a crear o reiniciar la consulta. Al cambiar los parámetros de la consulta, ésta se reiniciará automáticamente y los nuevos parámetros surtirán efecto.
Refiriéndonos al modelo de datos anterior, supongamos que desea obtener documentos en los que el número público-gustos está dentro de un rango determinado. En el ejemplo siguiente, buscamos "hotel". tipo documentos en los que el número de público-gustos está entre 5 y 10.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// 1. function that corresponds to the number of elements in an array let likesCount = ArrayFunction.length(Expression.property("public_likes")) // 2. Parameters for specifying lower and upper limits of range let lowerCount = Expression.parameter("lower") let upperCount = Expression.parameter("upper") // 3. Query that takes in parameters let searchQuery = QueryBuilder .select(SelectResult.expression(Meta.id), SelectResult.expression(Expression.property("name")), SelectResult.expression(likesCount).as("NumLikes") ) .from(DataSource.database(db)) .where(Expression.property("type").equalTo(Expression.string ("hotel")) .and(likesCount.between(lowerCount,and: upperCount))) .limit(Expression.int(limit)) // 4. Supplying the query parameter values let params = Parameters.init().setInt(5, forName: "lower").setInt(10, forName: "upper") searchQuery.parameters = params |
Tenga en cuenta que el ejemplo anterior, usted puede haber notado el uso de ArrayFunction. Couchbase Lite 2.0 nos proporciona un amplio soporte para la manipulación de arrays. Esto será discutido más adelante en este entrada del blog sobre colecciones.
¿Qué sigue?
Esta entrada de blog te dio un vistazo a la nueva y poderosa Interfaz de Consulta soportada en Couchbase Lite 2.0. Puedes descargar las versiones preliminares de Couchbase Mobile 2.0 desde nuestro descargas página.
Aquí hay otros posts relacionados con Couchbase Mobile Query que pueden ser de interés
- Este entrada del blog analiza las funciones de búsqueda de texto completo.
- Este entrada del blog explica cómo consultar colecciones de matrices
- 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.
Hola,
Después de actualizar Nuget Couchbase.Lite 2.1.2 parece que algunas de las funcionalidades de 1.3.1 han desaparecido como View:
var query = Provider.Db.GetView(viewName).CreateQuery();
query.AllDocsMode = AllDocsMode.AllDocs;
¿Cómo puedo encontrar en Couchbase.Lite 2.1.2 para obtener VIEW?
La interfaz QueryBuilder soporta una funcionalidad equivalente a la de Views, excepto que proporciona una forma más intuitiva de hacerlo. Su formato similar a SQL hace que sea más fácil de usar.
Si tiene preguntas específicas sobre lo que desea hacer y cómo hacerlo, envíe un ejemplo concreto a nuestros foros de desarrollo en http://www.couchbase.com/forums/. Antes de eso, le recomiendo que revise nuestros documentos en https://docs.couchbase.com/couchbase-lite/2.1/csharp.html. Hay varios ejemplos de como hacerlo en csharp.
¿Podría indicarme también cómo puedo actualizar el documento?
Tengo documentos de esta capacidad en móviles y ha estado funcionando mal en mi implementación actual(javascriptcore)
tamaño del documento: 600kb
líneas: 27000
caracteres totales:614386
Tenga la amabilidad de compartir una dirección para mi caso. Puedo seguir para cualquier detalle en los foros
Hay un pequeño error cuando mencionas En el ejemplo,
buscamos todos los documentos en los que la propiedad email sea nula o falte.
Para ello has utilizado el método notNullOrMissing() incorrecto en lugar de isNullOrMissing().
Por favor, actualice el documento.
Arreglado. Gracias
Hola,
después de actualizar a 2.6.3, el siguiente código no funciona
Function.contains(Function.lower(Expression.property("email")), substring: Expression.string("Sri@xxx.com"))
.or(Function.contains(Function.lower(Expression.property("asunto"))), substring: Expression.string("Sri@xxx.com")))
Lo siento, ha sido un error mío. Ignóralo.