Estoy jugando con Firebase Firestore para mis necesidades de datos. Tengo un modelo de datos donde hay una colección de manzanas, cada documento representa una manzana única que tiene un campo de tipo objeto que es esencialmente un mapa de <cadena, cadena>
Piense en cada documento de Apple como:
name: "SiberianApple", weight: "400g" color: { today: "green", yesterday: "red", tomorrow: "crimson" }
Leyendo los documentos, entendí que podemos consultar colecciones de varias maneras, pero ¿es posible limitar la cantidad de información que un cliente necesita obtener mientras obtiene un documento? ¿Puedo tener una consulta sobre este color
de campo de modo que solo devuelva
name: "SiberianApple", weight: "400g", color: { today: "green" }
Básicamente algo como graphql, donde puedo pedir lo que quiero. Quería saber si es posible consultar o si este campo debe ser una subcolección de este documento para poder consultar los colores usando la ruta apples/<appleId>/colors
para la subcolección.
Los oyentes de Cloud Firestore disparan en el nivel del documento. No hay forma de activarse solo con campos particulares en un documento o dividir el documento para obtener solo una propiedad. Es todo el documento o nada. Por lo tanto, los SDK del lado del cliente de Firestore siempre devuelven documentos completos. Desafortunadamente, no hay forma de solicitar solo una parte del documento.
¿Es posible limitar la cantidad de información?
Como se dijo, eso no es posible. Lo que puede hacer es crear otra colección con documentos que solo puedan contener los campos que necesita. Esta práctica se llama desnormalización y es una práctica bastante común cuando se trata de bases de datos NoSQL.
Como explicó Alex en su respuesta, con los SDK de cliente no es posible obtener solo un subconjunto de los campos de un documento. Cuando obtiene un documento, lo obtiene con todos sus campos.
Sin embargo, esto es posible con la API REST de Firestore : con la API REST puede usar un DocumentMask
cuando obtiene un documento con el método get
. DocumentMask
"restringirá una operación de obtención en un documento a un subconjunto de sus campos".
Para consultar varios documentos, es un poco diferente: usa el método runQuery
. El cuerpo de la solicitud deberá contener un objeto JSON que tenga una propiedad de consulta structuredQuery
.
A su vez, StructuredQuery
tiene una propiedad de select
que contiene un objeto de Projection
.
Este es un ejemplo de una carga útil utilizada al llamar al método runQuery
(es decir, https://firestore.googleapis.com/v1/{parent=projects/*/databases/*/documents}:runQuery
):
const payloadObj = { structuredQuery: { where: { // .... }, orderBy: [ { field: { fieldPath: 'name', }, direction: 'ASCENDING', }, ], from: [ { collectionId: 'apples', }, ], select: { fields: [ { fieldPath: 'name', }, { fieldPath: 'weight', }, { fieldPath: 'color.today', }, ], }, limit: 1000, }, };
Como puede ver en el código anterior, puede apuntar solo a una de las propiedades del mapa de color
, con fieldPath: 'color.today',
Nota final: la API REST es menos fácil de usar que los SDK del cliente porque necesita compilar la carga útil que se pasa a la solicitud y analizar las respuestas, pero no es difícil de usar. En una aplicación web, use fetch
, axios
o gaxios
para ejecutar las llamadas.