Campos fragmentados

En esta página, se describe cómo ver y controlar el uso de campos fragmentados en Firestore con compatibilidad con MongoDB. Esta función está disponible en la edición Enterprise de Firestore.

Cuando se escriben documentos, Firestore puede determinar que ciertos campos deben almacenarse en un formato fragmentado. Los campos fragmentados optimizan el rendimiento de las consultas, ya que solo leen los campos requeridos en lugar del documento completo.

Consultas que se benefician de los campos fragmentados

Las lecturas en campos fragmentados se aplican a las siguientes formas de consultas cuando están disponibles:

  • Consultas de agregación: Son las consultas que solo necesitan acceder a un subconjunto de campos para las operaciones de agregación. Por ejemplo:

    db.customers.aggregate(
      [
        { $match: { "account_balance" : { $lt : 0 } } },
        { $count: "total" }
      ]
    );
    

    o con group-by:

    db.customers.aggregate([
      { $match: { "account_balance" : { $lt : 0 } } },
      {
        $group: {
          _id: "$market_segment",
          avg_balance: { $avg: "$account_balance" }
        }
      }
    ]);
    
  • Consultas de proyección: Son consultas que solo devuelven un subconjunto específico de campos. Por ejemplo:

    db.customers.find({}, { family_name: 1, given_name: 1, _id: 0 });
    
  • Consultas de filtro: Son consultas de filtro en las que el motor de consultas de Firestore determina que es beneficioso usar campos fragmentados para filtrar documentos. Por ejemplo:

    db.customers.find({ given_name: "Alice" });
    

Cómo ver el uso de los campos fragmentados

Puedes usar Query Explain para verificar si una consulta usa campos fragmentados. El nodo TableScan en el plan de ejecución de la consulta incluye una sección Storage con las siguientes métricas:

  • Forma de escaneo:
    • shredded_fields_only: La consulta solo lee los campos fragmentados.
    • shredded_fields_backjoin: La consulta lee los campos fragmentados y se une con el documento original para otros campos.
  • Campos fragmentados utilizados: Es una lista de nombres de propiedades que se leen como campos fragmentados.
  • Recuento de verificaciones: Es un mapa de contadores para las verificaciones. Una nueva verificación significa volver a leer el documento completo original cuando se analizan los campos fragmentados. Esto puede suceder si el valor del campo en un documento supera los 8 KiB, lo que es demasiado grande para el almacenamiento de campos fragmentados.

Resultado de ejemplo

...
└── • TableScan
        source: **/customers
        order: UNDEFINED
        row range: (-∞..+∞)
        filter: $lt($account_balance_1, 0)
        output bindings: {$account_balance_1=account_balance, $market_segment_1=market_segment}
        variables: [$account_balance_1, $market_segment_1]

        Execution:
         records returned: 1,374
         latency: 26.58 ms
         post-filtered rows: 13,626
         records scanned: 15,000
         data bytes read: 23.73 MiB (24,887,141 B)

        Storage:
         scan shape: shredded_fields_only
         shredded fields used: [account_balance, market_segment]

Controla el uso de campos fragmentados

De forma predeterminada, Firestore con compatibilidad con MongoDB usa campos fragmentados cuando están disponibles. Puedes controlar este comportamiento con la opción tableScanMethod en los comentarios de la consulta.

Valores admitidos para tableScanMethod:

  • shreddedFieldsEnabled (predeterminado): Usa campos fragmentados cuando estén disponibles.
  • shreddedFieldsDisabled: No se usarán los campos fragmentados.
  • forceShreddedFields: La consulta falla si no se puede realizar un análisis de tabla con el análisis de campos fragmentados.

Cómo encontrar comandos

Usa el método .comment() para especificar opciones para un comando find:

db.customers.find(
  { account_balance: 0.0 }
).comment(
  {
    firestoreOptions: {
      tableScanMethod: "shreddedFieldsDisabled"
    }
  }
);

Comandos de agregación

Usa la opción comment en el parámetro de opciones de un comando aggregate:

db.customers.aggregate(
  [
    { $match: { "account_balance" : { $lt : 0 } } },
    { $count: "total" }
  ],
  {
    comment: {
      firestoreOptions: {
        tableScanMethod: "shreddedFieldsDisabled"
      }
    }
  }
);

Advertencias de rendimiento de las búsquedas

Firestore con compatibilidad con MongoDB puede emitir advertencias de rendimiento en el resultado de la explicación de la consulta cuando se detecta un uso ineficiente de campos fragmentados. Por ejemplo:

  • Consultas de baja selectividad: Si una consulta analiza campos fragmentados para filtrar, pero filtra pocos documentos, lo que hace que el análisis sea ineficiente.

  • Consultas con muchas revalidaciones: Si la consulta recurre a lecturas de documentos completos con frecuencia, lo que puede afectar el rendimiento. Puedes usar operadores como $bsonSize para identificar valores grandes que activan las verificaciones.

En estos casos, considera inhabilitar las lecturas de campos fragmentados con opciones de consulta.

Limitaciones

Firestore solo intenta fragmentar los campos de nivel superior. También restringe la cantidad de campos que se pueden fragmentar por colección.