Feast proporciona una API FeatureStore de alto nivel que le permite definir características y grupos de características (vistas de características), almacenamiento en línea y fuera de línea, y la capacidad de mover datos dinámicamente del almacenamiento fuera de línea al almacenamiento en línea (materialización). La integración conMongoDB permite usar MongoDB como almacenamiento en línea y fuera de línea para Feast, de modo que se pueden definir las características una sola vez y servirlas de forma consistente durante el entrenamiento del modelo y la inferencia en línea sin mantener sistemas de almacenamiento separados.
El modelo de documentos flexible de MongoDB y MQL le permiten gestionar los patrones de consulta complejos necesarios para la tienda física. Para la tienda en línea, MongoDB está optimizado para patrones de acceso a escala web: lecturas/escrituras rápidas, escalabilidad horizontal y esquemas flexibles que minimizan las uniones y los viajes de ida y vuelta.
En esta descripción general de la integración, encontrará:
Introducción a MongoDB como tienda online y offline de Feast.
Cómo se relacionan los conceptos de Feast con MongoDB.
Explicaciones detalladas de los diseños de tiendas online y offline de MongoDB.
Ejemplos de configuración para configurar los almacenes de MongoDB en Feast.
Conceptos clave
Tiendas online y físicas
La tienda en línea es un almacén de clave-valor respaldado por una única colección de MongoDB, optimizado para la recuperación de baja latencia de las últimas características por entidad durante la inferencia en línea.
El almacén sin conexión es una capa de computación y traducción que consulta filas de datos históricos de características almacenadas en una colección de MongoDB (normalmente llamada
feature_history) para conjuntos de datos de entrenamiento, puntuación y materialización (promoción de datos a la tienda en línea).
Patrones comunes de flujo de trabajo
Un flujo de trabajo típico de principio a fin se ve así:
Defina entidades, vistas de características y fuentes de datos que apunten a colecciones respaldadas por MongoDB.
Ingiere datos de características en el almacén fuera de línea a través de
offline_write_batch, que acepta una tabla PyArrow como entrada e inserta los datos en la colecciónfeature_historyde MongoDB siguiendo el esquema del almacén fuera de línea.Genera datos de entrenamiento usando
get_historical_features, que realiza una unión puntual eficiente sobre filas de características históricas almacenadas en MongoDB.Materializa los últimos valores de características de la tienda física en la tienda en línea usando
pull_latest_from_table_or_queryyonline_write_batch.Las funcionalidades se ofrecen en línea a través de las API en línea de Feast, que leen datos de una única colección de MongoDB indexada por una clave de entidad serializada.
Cómo se relacionan los conceptos de Feast con MongoDB
La integración con MongoDB sigue el modelo conceptual estándar de Feast, pero asigna esas abstracciones a un esquema de MongoDB diseñado para documentos en línea centrados en entidades y eventos históricos de solo adición.
Mapeo conceptual
Concepto de banquete | Papel en el banquete | Representación de MongoDB |
|---|---|---|
Entidad | Objeto de dominio que describen las características (por ejemplo, conductor, usuario). | Codificado en una clave de entidad serializada; almacenado como |
Clave de acceso | Columna(s) utilizada(s) para identificar una fila de entidad en un dataframe. | Se introduce en |
Clave de entidad serializada | Codificación binaria determinista de los nombres y valores de las claves de unión. | En línea: |
funcionalidad | Medición nombrada y escrita en un momento determinado. | Un campo dentro del subdocumento |
FeatureView | Vincula características a entidades, fuente de datos y TTL; unidad de organización. | Sin conexión: cadena discriminadora |
DataSource | Los metadatos indican dónde se encuentran las características históricas. |
|
Tienda sin conexión | Interfaz de lectura/escritura para características históricas y uniones PIT. |
|
OnlineStore | Almacenamiento de baja latencia de los valores de características más recientes por entidad. | Colección única de MongoDB de documentos de entidades indexados por |
TTL | Ventana de frescura a nivel de FeatureView. | Se aplica en consultas sin conexión y en el postfiltrado de Python al calcular características históricas; también se puede combinar con |
Servicio de características | Lista con nombre de referencias de características para un modelo. | No hay representación directa en MongoDB; Feast la utiliza para decidir qué rutas |
Registro | Almacén de metadatos para entidades, vistas de características y servicios. | Sin cambios; la integración con MongoDB no reemplaza el registro de Feast. |
RetrievalJob | Envoltorio de ejecución diferida que devuelve tablas de características. | Para el almacenamiento sin conexión de MongoDB, encapsula una agregación MQL y expone exportaciones Arrow respaldadas por una conversión de cursor a Arrow. |
Materialización | Propagación programada de las últimas funciones offline a la tienda online. | Implementado a través de |
Tienda sin conexión de MongoDB
modelo de datos
El almacenamiento sin conexión de MongoDB utiliza una única colección compartida (por defecto feature_history) que almacena filas de características históricas de solo adición para todas las vistas de características.
Cada documento representa una observación de una entidad para una FeatureView en una marca de tiempo de evento específica:
{ "entity_id": "Binary(...)", "feature_view": "driver_stats", "event_timestamp": "ISODate(2024-01-15T12:00:00Z)", "created_at": "ISODate(2024-01-15T12:01:00Z)", "features": { "conv_rate": 0.72, "acc_rate": 0.91, "avg_daily_trips": 14 } }
Propiedades clave:
Solo anexar: los datos históricos se tratan como inmutables; las correcciones se escriben como nuevas filas con marcas de tiempo
created_atmás recientes en lugar de actualizaciones en el mismo lugar.Compatible con series temporales:
event_timestamprepresenta el momento en que se observó el valor de la característica;created_atse utiliza como criterio de desempate cuando varias observaciones comparten la misma marca de tiempo del evento.Agrupación de características por FeatureView:
feature_viewidentifica a qué FeatureView pertenece la fila, por lo que una sola colección puede albergar múltiples FV.
Un único índice compuesto admite todos los patrones de consulta principales:
(entity_id ASC, feature_view ASC, event_timestamp DESC, created_at DESC)
Este índice permite realizar escaneos de rango eficientes sobre entidades y vistas de características, al tiempo que garantiza que la observación más reciente por (entity_id, feature_view) se vea primero durante la agregación.
Patrón de consulta | Comportamiento del índice |
|---|---|
| Exploración de rango de índice en el prefijo |
| La ordenación no tiene efecto: el orden de los índices coincide con el orden de clasificación. |
| El cursor visita primero el último documento por |
|
|
Sin este índice, los cuatro patrones de consulta se degradan a COLLSCAN. El índice se crea de forma diferida en el primer uso a través de _ensure_indexes, se almacena en caché por cadena de conexión en un conjunto _indexes_ensured a nivel de proceso, por lo que solo se crea una vez durante la vida útil del proceso.
Operaciones principales fuera de línea
El almacén sin conexión de MongoDB implementa la interfaz estándar de almacén sin conexión de Feast:
offline_write_batch- Escribe unpyarrow.Tablede datos de características en la colección subyacente de MongoDB, utilizando los metadatosMongoDBSourceconfigurados para determinarconnection_string,databaseycollection.get_historical_features- Dado unentity_dfde entidades y marcas de tiempo de eventos más un conjunto de FeatureViews, devuelve una tabla ampliada donde cada fila incluye valores de características correctos en un punto en el tiempo: para cada par(entity_id, event_timestamp), se selecciona el valor de característica más reciente cuyoevent_timestamp <= entity_event_timestampy dentro de TTL.pull_latest_from_table_or_query- Devuelve una fila por entidad que contiene los valores de características más recientes en un intervalo de tiempo, utilizados por el motor de materialización de Feast para alimentar la tienda en línea.pull_all_from_table_or_query- Recupera todas las filas de una fuente de datos en un rango de fechas especificado para su exportación o inspección, respaldadas por el mismo esquemafeature_historye índice.persist(a través deRetrievalJob.persist) - Escribe el resultado de una consulta de características históricas en una colección separada o un destino externo a través deSavedDatasetStorage, distinto defeature_history.
Ruta de llamada:
FeatureStore.write_to_offline_store(feature_view_name, df) → provider.ingest_df_to_offline_store(feature_view, arrow_table) → OfflineStore.offline_write_batch(config, feature_view, table, progress)
Semántica de solo anexar: Los documentos se insertan con insert_many(ordered=False) en 10 000lotes de, documentos. No hay inserción ni actualización ni deduplicación en el momento de la escritura: se (entity_id, feature_view, event_timestamp) permiten y se conservan varios documentos para la misma tupla.
Laresolución del conflicto se pospone hasta el tiempo de lectura:
pull_latest_from_table_or_queryelige el documento con elcreated_atmás alto dentro del grupoevent_timestampganador.get_historical_features(ruta de puntuación) utiliza$sort … created_at DESCpor lo que$group $firsttambién selecciona elcreated_atmás alto cuando las marcas de tiempo empatan.
Por lo tanto, una corrección escrita con un created_at posterior prevalece sin necesidad de ninguna operación de eliminación o actualización.
pull_latest_from_table_or_query Devuelve una fila por entidad con los valores de características más recientes en una ventana [start_date, end_date]. No se proporciona ningún entity_df.
Etapas del proceso:
$match { feature_view, event_timestamp: {$gte, $lte} } → $sort { entity_id, event_timestamp DESC, created_at DESC } → $group $first by entity_id → $project { entity_id, event_timestamp, features.* }
El índice compuesto sirve a $match + $sort de manera eficiente; $group $first selecciona un documento por entidad sin materializar el resto.
Implementación de agregación
La implementación sin conexión recomendada es el almacén sin conexión de MongoDB basado en agregación, llamado MongoDBOfflineStore.
Características clave:
Utiliza una única colección
feature_historycompartida por todas las FeatureViews, distinguida porfeature_view.Se basa en el índice compuesto
(entity_id, feature_view, event_timestamp, created_at)para todas las consultas, evitando escaneos completos de la colección.Utiliza
$group $firstdel lado del servidor para cargas de trabajo de "puntuación" (una fila por entidad) ypd.merge_asofpara cargas de trabajo de "entrenamiento" con ID de entidad repetidos, equilibrando la corrección y el rendimiento.El uso limitado de memoria mediante la división en bloques permite procesar valores
entity_dfgrandes sin agotar la RAM.
Las pruebas de rendimiento demuestran que esta implementación ofrece la mejor combinación de rendimiento y eficiencia de memoria en comparación con otros enfoques sin conexión para MongoDB.
get_historical_features es la API principal de Feast. Acepta un entity_df (N filas de columnas de clave de entidad + event_timestamps) y K FeatureView objetos y devuelve un DataFrame con las mismas N filas más M columnas de características, con valores correctos en el event_timestamp de cada fila (corrección en un punto en el tiempo).
Notación:
N → número de entidades
M → número de características
P → número de observaciones
F → número de vistas de características
K → número de vistas de características solicitadas en una sola llamada
get_historical_features
Ruta de puntuación
La ruta de puntuación se activa cuando entity_df no tiene identificadores de entidad repetidos, el escenario de inferencia común donde cada fila solicita las características de una entidad distinta en un momento distinto.
Detección:
scoring_path = ( entity_df[all_entity_id_cols].drop_duplicates().shape[0] == len(entity_df) )
Al puntuar, se añade la etapa $group $first del lado del servidor:
$match → $sort → $group $first → $project
El $group agrupa por (entity_id, feature_view) y selecciona el documento con el (event_timestamp, created_at) más alto, es decir, el primer documento en orden de índice después del $sort precedente. MongoDB nunca materializa los otros P-1 documentos para cada entidad por vista de característica; el cursor simplemente avanza a la siguiente clave de grupo después de seleccionar un documento. El costo por entidad es O(log P) (búsqueda de índice) en lugar de O(P).
El $match utiliza event_timestamp: {$lte: max_ts} donde max_ts es la marca de tiempo máxima de solicitud de entidad en el fragmento actual. Esta es una aproximación conservadora (el "sobreimpulso"): el servidor puede devolver documentos ligeramente en el futuro para algunas entidades. El postfiltro de Python que se muestra a continuación corrige esto al anular las filas no válidas:
# Merge on entity_id (left = entity_df rows, right = server results) merged = result[["_fv_entity_id", event_timestamp_col]].merge( fv_join, on="_fv_entity_id", how="left" ) # Null out rows where the server doc is in the future or outside TTL future_mask = merged["_fv_ts"] > merged[event_timestamp_col] if fv.ttl: ttl_mask = merged["_fv_ts"] < ( merged[event_timestamp_col] - fv.ttl ) bad_mask = future_mask | ttl_mask else: bad_mask = future_mask for feat in features: vals = merged[feat].copy() vals[bad_mask | merged["_fv_ts"].isna()] = None result[col] = vals.values
Se trata de una única llamada pd.merge seguida de una indexación booleana vectorizada: trabajo O(N) en código C de Pandas, independiente de P y M.
Trayectoria de formación
Cuando entity_df tiene identificadores de entidad repetidos (un conjunto de datos de entrenamiento con muchas instantáneas de marca de tiempo por entidad), se omite la etapa $group. La agregación devuelve todos los documentos en la ventana de marca de tiempo para cada entidad, y Python usa pd.merge_asof para encontrar el documento más reciente en o antes de event_timestamp de cada fila:
$match → (no $group)
result = pd.merge_asof( result.sort_values(event_timestamp_col), fv_df_subset.sort_values("_fv_ts"), left_on=event_timestamp_col, right_on="_fv_ts", by="_fv_entity_id", direction="backward", )
Dos niveles de segmentación controlan el uso de la memoria:
Nivel | Constante | Propósito |
|---|---|---|
Exterior | 50,000 filas | Limita la porción |
Interno | 10,000 identificadores de entidad | Limita el tamaño del array |
Para entity_df mayor que CHUNK_SIZE, el bucle exterior ejecuta múltiples llamadas _run_single y concatena los resultados:
if len(working_df) <= CHUNK_SIZE: result_df = _run_single(working_df, coll) else: chunks = [ _run_single(chunk, coll) for chunk in _chunk_dataframe(working_df, CHUNK_SIZE) ] result_df = pd.concat(chunks, ignore_index=True)
Por lo tanto, la memoria máxima del lado de Python es O(CHUNK_SIZE x M x K) independientemente del N total.
El subdocumento features de MongoDB se expande en columnas individuales usando pd.apply en lugar de pd.json_normalize. Esto preserva los tipos complejos (diccionarios para Map y Struct, listas para Array) que json_normalize aplanaría o perdería. También se aplica el mapeo inverso de campos para que los nombres de las columnas proyectadas coincidan con la definición de FeatureView:
if "features" in fv_df.columns: for feat in features: src_col = reverse_fm.get(feat, feat) fv_df[feat] = fv_df["features"].apply( lambda d, _s=src_col: ( d.get(_s) if isinstance(d, dict) else None ) ) fv_df = fv_df.drop(columns=["features"])
Capacidades de la tienda física
Capacidad | ¿Compatible? | notas |
|---|---|---|
| Sí | Implementado a través de |
| Sí | Utiliza |
| Sí | Análisis histórico completo con filtros de tiempo sobre |
| Sí | Escribe tablas Arrow en MongoDB a través del |
| Sí | Exporta los resultados de consultas históricas a una colección separada usando |
Las ventajas adicionales, como la exportación directa a lagos de datos o almacenes de datos, dependen de la implementación específica de RetrievalJob y se espera que sigan los patrones estándar de Feast para tiendas sin conexión.
Tienda en línea de MongoDB
modelo de datos
La tienda online de MongoDB utiliza una única colección para todas las FeatureViews, indexada por la clave de entidad serializada.
_id:serialized_entity_key(entity_key), producido por la función de codificación estable de Feast que ordena los nombres y valores de las entidades y los codifica en bytes.features: subdocumento anidado donde cada FeatureView mantiene su propio espacio de nombres de características.event_timestamps: marcas de tiempo por FeatureView que indican cuándo se escribió el último valor para esa FeatureView.created_timestampoupdated_at: campos de contabilidad útiles para la indexación TTL y el diagnóstico.
Ejemplo (simplificado):
{ "_id": "b\"<serialized_entity_key>\"", "features": { "driver_stats": { "rating": 4.91, "trips_last_7d": 132 }, "pricing": { "surge_multiplier": 1.2 } }, "event_timestamps": { "driver_stats": "ISODate(2026-01-01T12:00:00Z)", "pricing": "ISODate(2026-01-21T12:00:00Z)" }, "created_timestamp": "ISODate(2026-01-21T12:00:00Z)" }
Fundamentación del diseño:
Una única colección mantiene el estado de cada entidad en un solo documento, lo que coincide con la expectativa de Feast de realizar búsquedas basadas en claves y evita la fragmentación del estado en colecciones por FeatureView.
El uso de la clave de entidad serializada como
_idreutiliza la codificación determinista de Feast, evita claves primarias duplicadas en diferentes colecciones y mantiene la recuperación en una única búsqueda de clave por entidad.
Al igual que la tienda física (que utiliza una única colección feature_history con un campo discriminador feature_view), la tienda en línea también utiliza una única colección para todas las FeatureViews.
La tienda en línea se basa fundamentalmente en claves de entidad, no en vistas de características. Si bien la API de alto nivel FeatureStore invoca online_read y online_write_batch con una sola FeatureView, el modelo de almacenamiento subyacente en Feast está diseñado en torno a una única fila lógica por clave de entidad. Dicha fila puede acumular características de múltiples FeatureViews con el tiempo.
El uso de una sola colección nos permite mantener un documento unificado por entidad y actualizar solo el subdocumento relevante (por ejemplo, features.<feature_view_name>) de forma atómica sin duplicar las claves de entidad en todas las colecciones.
Desde sus inicios, Feast adoptó un diseño de colección única (originalmente diseñado para Redis), que aprovecha las fortalezas de MongoDB. Entre sus ventajas se incluyen:
Amplificación de escritura reducida
Gestión de índices simplificada (un único índice primario
_id)No hay coordinación entre colecciones cuando varias FeatureViews comparten las mismas entidades.
Semántica de recuperación consistente con el modelo de recuperación basado en claves de Feast.
Un diseño de colección por FeatureView fragmentaría el estado de la entidad, requeriría coordinación adicional o consultas de múltiples colecciones si las características se componen alguna vez, e incrementaría la sobrecarga operativa sin una ventaja de rendimiento para el patrón de acceso de Feast.
Clave de entidad serializada como _id: Feast proporciona serialize_entity_key, una función de codificación estable que ordena explícitamente los nombres y valores de las entidades antes de la concatenación para garantizar una secuencia de bytes predecible (tipada con struct.pack que produce bytes). Esto significa que podemos usarla directamente como _id.
Nota
Si bien serialize_entity_key proporciona un _id estable, su salida no se distribuye uniformemente y, por lo tanto, no es ideal para la fragmentación. Si su implementación requiere fragmentar la colección de la tienda en línea, considere usar una clave de fragmentación con hash o un campo adicional.
Operaciones principales en línea
La tienda online de MongoDB implementa la API estándar de tienda online de Feast:
online_write_batch- Durante la materialización, Feast escribe los valores de características más recientes para cada entidad en documentos de MongoDB. Cada operación de inserción/actualización por lotes actualiza solo el subdocumento anidadofeatures.<feature_view>relevante y su entrada correspondiente enevent_timestamps, manteniendo los documentos de entidad atómicos y consistentes.online_readyget_online_features- El servicio en línea resuelve las claves de entidad en valores_idutilizando la misma lógica de serialización que fuera de línea, luego realiza búsquedas de claves. Cada búsqueda devuelve todas las características solicitadas para la entidad en un solo viaje de ida y vuelta, aprovechando la estructura anidadafeatures.TTL y actualidad: el TTL de la característica se configura en FeatureView y se utiliza principalmente en uniones PIT fuera de línea; el TTL en línea se puede implementar con un índice en
updated_ato una marca de tiempo similar, de acuerdo con la noción de Feast de que los almacenes fuera de línea son solo de adición, mientras que los almacenes en línea mantienen el estado más reciente.
Configuración
Configuración de la tienda sin conexión
La tienda sin conexión está configurada usando MongoDBOfflineStoreConfig:
class MongoDBOfflineStoreConfig(FeastConfigBaseModel): type: str = "...MongoDBOfflineStore" connection_string: str = "mongodb://localhost:27017" database: str = "feast" collection: str = "feature_history"
Ejemplo feature_store.yaml:
offline_store: type: feast.infra.offline_stores.contrib.mongodb_offline_store.mongodb.MongoDBOfflineStore connection_string: "mongodb+srv://user:pass@cluster.mongodb.net" database: feast collection: feature_history
MongoDBSource es el DataSource correspondiente. Su name campo se convierte en el feature_view discriminador almacenado en cada documento. Para ver todas las opciones de configuración, consulte la referencia de la fuente de datos de MongoDB en la documentación de Feast.
source = MongoDBSource( name="driver_stats", timestamp_field="event_timestamp", created_timestamp_column="created_at", )
Próximos pasos
Sigue la guía de inicio rápido de Feast para configurar un almacén de características local y, a continuación, cámbialo por MongoDB como almacén en línea y fuera de línea utilizando los ejemplos de configuración de esta página.
Consulte la referencia de MongoDB Online Store en la documentación de Feast para obtener información sobre las opciones de configuración, la compatibilidad con operaciones asíncronas y la matriz completa de funcionalidades.
Consulte la documentación de referencia de MongoDB Offline Store para obtener información sobre la configuración y las funcionalidades compatibles con el almacenamiento sin conexión.
Revise la referencia de la fuente de datos de MongoDB para
MongoDBSourceconocer las opciones y los detalles del esquema.Aprende los conceptos básicos de Feast, como entidades, vistas de características y materialización, en la guía de conceptos de Feast.