O Feast fornece uma API FeatureStore de alto nível que permite definir feições e grupos de feições ( visualizações defeições), armazenamento online e offline e a capacidade de mover dinamicamente dados do armazenamento offline para o online (materialização). A integração do MongoDB permite que você use o MongoDB como uma loja online e offline para o Feast, para que você possa definir os recursos uma vez e servi-los consistentemente por meio do treinamento de modelos e da inferência online sem manter sistemas de armazenamento separados.
O modelo de documento flexível e o MQL do MongoDB permitem que ele lide com os padrões de query complexos necessários para o armazenamento offline. Para a loja online, o MongoDB é otimizado para padrões de acesso em escala web – leituras/gravações rápidas, dimensionamento horizontal e esquemas flexíveis que minimizam junções e idas e voltas.
Nesta visão geral da integração, você pode encontrar:
Uma introdução ao MongoDB como a loja online e offline da Feast.
Como os conceitos de Feast são mapeados para o MongoDB.
Explicações detalhadas dos projetos de loja offline e online do MongoDB .
Exemplos de configuração para configurar as lojas MongoDB no Feast.
Conceitos chave
Lojas online e offline
A loja online é um armazenamento de valores-chave apoiado por uma única coleção do MongoDB , otimizado para recuperação de baixa latência dos recursos mais recentes por entidade durante a inferência online.
A loja offline é uma camada de computação e tradução que query linhas de dados históricos de funcionalidades armazenados em uma collection do MongoDB (normalmente chamada) para conjuntos de dados
feature_historyde treinamento, pontuação e materialização (promoção de dados para o armazenamento online).
Padrões comuns de fluxo de trabalho
Um fluxo de trabalho típico de ponta a ponta é assim:
Defina entidades, visualizações de recursos e fontes de dados que ponto para coleções apoiadas MongoDB.
A ingestão de dados de funcionalidades no armazenamento offline por meio do
offline_write_batch, que aceita uma tabela PyArrow como entrada e insere os dados na coleçãofeature_historyMongoDB seguindo o esquema do armazenamento offline.Gere dados de treinamento usando o
get_historical_features, que executa uma conexão eficiente de ponto no tempo em linhas de recursos históricos armazenadas no MongoDB.Materialize os valores de funcionalidades mais recentes da loja offline para a loja online usando
pull_latest_from_table_or_queryeonline_write_batch.Disponibilize recursos online por meio das APIs online do Feast, que leem de uma única coleção do MongoDB chaveada por uma chave de entidade serializada.
Como os conceitos de festividade são mapeados para o MongoDB
A integração do MongoDB segue o modelo conceitual padrão da Feast, mas mapeia essas abstrações para um esquema do MongoDB projetado para documentos online focados em entidades e eventos históricos somente para anexar.
Mapeamento de conceitos
Conceito de festividade | Role na festividade | Representação do MongoDB |
|---|---|---|
Entidade | objeto de domínio que os recursos descrevem (por exemplo, motorista, usuário). | Codificado em uma chave de entidade serializada; armazenado como |
Chave de acesso | Coluna(s) usada(s) para identificar uma linha de entidade em um dataframe. | Distribuído em |
Chave de entidade serializada | Codificação binária determinística de nomes e valores de chave de junção. | On-line: |
funcionalidade | Medição nomeada e digitada em um ponto no tempo. | Um campo dentro do subdocumento |
FeatureView | Vincula feições a entidades, fonte de dados e TTL; unidade de organização. | Offline: |
DataSource | Ponteiro de metadados para onde as características históricas ao vivo. |
|
OfflineStore | Interface de leitura/gravação para recursos históricos e entradas de PIT. |
|
OnlineStore | Armazenamento de baixa latência dos valores de recursos mais recentes por entidade. | Collection única do MongoDB de documentos de entidade chaveados por |
TTL | Janela de atualização no nível do FeatureView. | Aplicado em queries offline e pós-filtragem do Python ao calcular funcionalidades históricas; também pode ser combinado com |
FeatureService | Lista nomeada de referências de recursos para um modelo. | Nenhuma representação direta do MongoDB ; usado pelo Feast para decidir quais |
Registro | Armazenamento de metadados para entidades, visualizações de recursos e serviços. | Inalterado; A integração do MongoDB não substitui o registro Feast. |
RetrievalJob | Tabelas de recursos de retorno do wrapper de execução adiada. | Para a loja offline do MongoDB , encapsula uma agregação MQL e expõe exportações de setas apoiadas pela conversão de cursor para seta. |
Materialização | Propagação programada dos recursos offline mais recentes na loja online. | Implementado via |
Loja offline do MongoDB
Modelo de dados
O armazenamento offline do MongoDB usa uma única coleção compartilhada (por padrão feature_history) que armazena linhas de recursos históricos somente anexados para todas as visualizações de recursos.
Cada documento representa uma observação de uma entidade para um FeatureView em um registro de data/hora de evento específico:
{ "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 } }
Propriedades principais:
Somente anexar: os dados históricos são tratados como imutáveis; as correções são escritas como novas linhas com registros de data/hora
created_atmais recentes em vez de atualizações no local.Compatível com séries temporais:
event_timestamprepresenta quando o valor do recurso foi observado;created_até usado como desempate quando várias observações compartilham o mesmo carimbo de data/hora do evento .Agrupamento de recursos por FeatureView:
feature_viewidentifica a qual FeatureView a linha pertence, de modo que uma única coleção possa hospedar vários FVs.
Um único índice composto suporta todos os principais padrões de query:
(entity_id ASC, feature_view ASC, event_timestamp DESC, created_at DESC)
Esse índice permite varreduras de intervalo eficientes sobre entidades e visualizações de recursos, enquanto garante que a observação mais recente por (entity_id, feature_view) seja vista primeiro durante a agregação.
Padrão de query | Comportamento do índice |
|---|---|
| Varredura de faixa de índice no prefixo |
| A classificação é um no-op — a ordem do índice corresponde à ordem de classificação. |
| O cursor visita o documento mais recente por |
|
|
Sem esse índice, todos os quatro padrões de query são degradados para COLLSCAN. O índice é criado lentamente no primeiro uso por meio de _ensure_indexes, armazenado em cache por string de conexão em um conjunto _indexes_ensured no nível do processo, portanto, é criado apenas uma vez por tempo de vida do processo.
Principais operações offline
A loja offline do MongoDB implementa a interface de loja offline padrão do Feast:
offline_write_batch- Grava umpyarrow.Tabledos dados de funcionalidades na collection subjacente do MongoDB , usando os metadadosMongoDBSourceconfigurados para determinarconnection_string,databaseecollection.get_historical_features- Dado umentity_dfde entidades e registros de data/hora de evento , além de um conjunto de FeatureViews, retorna uma tabela ampliada em que cada linha inclui valores de recursos corretos point-in-time: para cada par(entity_id, event_timestamp), o valor de recurso mais recente cujoevent_timestamp <= entity_event_timestampe dentro de TTL estiver selecionado.pull_latest_from_table_or_query- Retorna uma linha por entidade contendo os valores de funcionalidade mais recentes em uma janela de tempo, usada pelo mecanismo de materialização do Feast para semear a loja online.pull_all_from_table_or_query- Recupera todas as linhas de uma fonte de dados em um intervalo de datas especificado para exportação ou inspeção, apoiado pelo mesmo esquema e índice dofeature_history.persist(viaRetrievalJob.persist) - Grava o resultado de uma query de recurso histórico em uma coleção separada ou coletor externo viaSavedDatasetStorage, distinto defeature_history.
Caminho da chamada:
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 somente anexa: os documentos são inseridos com insert_many(ordered=False) 10em,000- lotes de documento . Não há upsert ou eliminação de duplicação no momento da gravação — vários documentos para a mesma (entity_id, feature_view, event_timestamp) tupla são permitidos e retidos.
Aresolução de conflitos é adiada para o tempo de leitura:
pull_latest_from_table_or_queryescolhe o documento com a maiorcreated_atdentro do grupoevent_timestampvencedor.get_historical_features(caminhos de pontuação) usa$sort … created_at DESC, portanto,$group $firsttambém seleciona ocreated_atmais alto quando os registros de data e hora se vincularem.
Uma correção escrita com um created_at posterior vence sem qualquer operação de exclusão ou atualização.
pull_latest_from_table_or_query retorna uma linha por entidade com os valores de feição mais recentes em uma janela [start_date, end_date]. Nenhum entity_df é fornecido.
Estágios do pipeline:
$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.* }
O índice composto atende $match + $sort eficientemente; $group $first escolhe um documento por entidade sem materializar o resto.
Implementação de agregação
A implementação offline recomendada é o armazenamento offline do MongoDB baseado em aggregation, denominado MongoDBOfflineStore.
Características principais:
Utiliza uma única coleção
feature_historycompartilhada por todos os FeatureViews, distinguidos porfeature_view.Confia no índice composto
(entity_id, feature_view, event_timestamp, created_at)para todas as queries, evitando varreduras completas da coleção.Usa o
$group $firstdo lado do servidor para cargas de trabalho de "pontuação" (uma linha por entidade) epd.merge_asofpara cargas de trabalho de "treinamento" com IDs de entidade repetidas, equilibrando correção e desempenho.Uso de memória limitada por meio de agrupamento, portanto, valores
entity_dfgrandes podem ser processados sem esgotar a RAM.
Os benchmarks mostram que essa implementação fornece a melhor combinação de taxa de transferência e eficiência de memória em comparação com abordagens offline alternativas do MongoDB .
get_historical_features é a API principal do Feast. Ele aceita um entity_df (N linhas de colunas de chave de entidade + event_timestamps) e K FeatureView objetos e retorna um DataFrame com as mesmas linhas N mais colunas de recurso M, com valores corretos no event_timestamp de cada linha (ponto- correção in-time).
Notação:
N → número de entidades
M → número de funcionalidades
P → número de observações
F → número de visualizações de recursos
K → número de visualizações de funcionalidades solicitadas em uma única
get_historical_featureschamada
Caminho de pontuação
O caminho de pontuação é ativado quando entity_df não tem IDs de entidade repetidos — o cenário de inferência comum em que cada linha solicita as funcionalidades de uma entidade distinta em um ponto de tempo distinto.
Detecção:
scoring_path = ( entity_df[all_entity_id_cols].drop_duplicates().shape[0] == len(entity_df) )
Ao pontuar, o estágio $group $first do lado do servidor é adicionado:
$match → $sort → $group $first → $project
O $group agrupa por (entity_id, feature_view) e escolhe o documento com o (event_timestamp, created_at) mais alto — ou seja, o primeiro documento na ordem do índice após o $sort anterior. O MongoDB nunca materializa os outros documentos P-1 para cada entidade por visualização de recurso; o cursor simplesmente avança para a próxima chave de grupo depois de escolher um documento. O custo por entidade é O(log P) (busca do índice) em vez de O(P).
O $match usa event_timestamp: {$lte: max_ts}, em que max_ts é o carimbo de data/hora máximo de solicitação de entidade no chunk atual. Esta é uma aproximação conservadora ("Oversync"): o servidor pode retornar documentos ligeiramente no futuro para algumas entidades. O pós-filtro do Python abaixo corrige isso anulando linhas invá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
Esta é uma única chamada pd.merge seguida de indexação booleana vetorizada — O(N) funciona no código Pandas C, independente de P e M.
Caminho de treinamento
Quando entity_df tem IDs de entidade repetidos (um conjunto de dados de treinamento com muitos snapshots de registros de data/hora por entidade), o estágio $group é omitido. A agregação retorna todos os documentos na janela de registro de data/hora para cada entidade, e o Python usa pd.merge_asof para localizar o documento mais recente em ou antes do event_timestamp de cada linha:
$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", )
Dois níveis de agrupamento controlam o uso da memória:
Nível | Constante | Propósito |
|---|---|---|
Externo | 50,000 linhas | Limita a fatia |
Interno | 10,000 IDs de entidade | Limita o tamanho da array |
Para entity_df maiores que CHUNK_SIZE, o loop externo executa várias chamadas _run_single e concatena os 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)
O pico da memória do lado do Python é, portanto, O(CHUNK_SIZE x M x K), independentemente do total de N.
O subdocumento features do MongoDB é expandido em colunas individuais usando pd.apply em vez de pd.json_normalize. Isso preserva os tipos complexos (dicts para Map e Struct, listas para Array) que json_normalize nivelariam ou perderiam. O mapeamento de campo reverso também é aplicado para que os nomes das colunas projetadas correspondam à definição 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"])
Recursos da loja offline
Capacidade | Suportado? | Notas |
|---|---|---|
| Sim | Implementado via |
| Sim | Usa |
| Sim | Varredura histórica completa com filtros de tempo acima de |
| Sim | Escreve tabelas de seta no MongoDB através do |
| Sim | Exporta resultados históricos da query para uma collection separada usando |
Conveniências adicionais, como exportar diretamente para data lakes ou armazéns, dependem da implementação específica do RetrievalJob e espera-se que siga os padrões padrão da Feast para armazenamentos offline.
Loja virtual do MongoDB
Modelo de dados
A loja online MongoDB usa uma única coleção para todos os FeatureViews, codificados pela chave de entidade serializada.
_id:serialized_entity_key(entity_key), produzido pela função de codificação estável do Feast que classifica os nomes e valores das entidades e os codifica em bytes.features: subdocumento aninhado onde cada FeatureView mantém seu próprio namespace de funcionalidade .event_timestamps: carimbos de data/hora por FeatureView que indicam quando o valor mais recente para esse FeatureView foi gravado.created_timestampouupdated_at: campos de contabilidade úteis para indexação e diagnóstico de TTL.
Exemplo (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)" }
Fundamento do design:
Uma única collection mantém o estado de cada entidade em um documento, o que corresponde à expectativa do Feast de pesquisas baseadas em chaves e evita a fragmentação do estado nas collections por FeatureView.
O uso da chave de entidade serializada como
_idreutiliza a codificação determinística do Feast, evita chaves primárias duplicadas entre collections e mantém a recuperação para uma única pesquisa de chave por entidade.
Como a loja offline (que usa uma única coleção feature_history com um campo discriminador feature_view), a loja online também usa uma única coleção para todos os FeatureViews.
A Loja Online é fundamentalmente orientada por chaves de entidade, e não por visualizações de recursos. Embora a API FeatureStore de alto nível invoque online_read e online_write_batch com um único FeatureView, o modelo de armazenamento subjacente no Feast é projetado em torno de uma única linha lógica por chave de entidade. Essa linha pode acumular recursos de vários FeatureViews ao longo do tempo.
O uso de uma collection nos permite manter um documento unificado por entidade e atualizar somente o subdocumento relevante (por exemplo, features.<feature_view_name>) atomicamente sem duplicar as chaves de entidade entre collections.
Um único design de coleção foi o padrão para o Feast desde o início (foi originalmente projetado para o Redis) e joga com os pontos fortes do MongoDB. Os benefícios incluem:
Amplificação de gravação reduzida
Gerenciamento de índice simplificado (somente um índice
_idprimário)Sem coordenação entre coleções quando vários FeatureViews compartilham as mesmas entidades
Semântica de recuperação consistente com o modelo de busca baseado em chaves do Feast
Um design de coleção por FeatureView fragmentaria o estado da entidade, exigiria coordenação adicional ou queries de várias coleções se os recursos fossem compostos e aumentasse a sobrecarga operacional sem uma vantagem de desempenho para o padrão de acesso do Feast.
Chave de entidade serializada como _id: o Feast fornece serialize_entity_key, uma função de codificação estável que classifica explicitamente os nomes e valores da entidade antes da concatenação para garantir uma sequência de bytes previsível ( digitada com struct.pack bytes de produção). Isso significa que podemos usá-lo diretamente _id como.
Observação
Embora serialize_entity_key forneça um _id estável, sua saída não é distribuída uniformemente e, portanto, não é ideal para fragmentação. Se a sua implementação exigir a fragmentação da collection da loja online, considere uma chave de fragmento com hash ou um campo adicional .
Operações Online Centrais
A loja online do MongoDB implementa a API de loja online padrão da Feast:
online_write_batch- Durante a materialização, o Feast grava os valores de funcionalidade mais recentes para cada entidade nos documentos do MongoDB . Cada upsert de lote atualiza somente o subdocumentofeatures.<feature_view>aninhado relevante e sua entrada correspondente emevent_timestamps, mantendo os documentos da entidade atômicos e consistentes.online_readeget_online_features- A entrega online resolve as chaves de entidade em valores_idusando a mesma lógica de serialização que offline e, em seguida, realiza pesquisas de chaves. Cada pesquisa retorna todas as feições solicitadas para a entidade em uma única viagem de ida e volta, aproveitando a estruturafeaturesaninhada.TTL e atualização — O recurso TTL é configurado no FeatureView e usado principalmente em junções de PIT offline; O TTL online pode ser implementado com um índice em
updated_atou registro de data e hora semelhante, consistente com a noção da Feast de que as lojas offline são somente para anexação, enquanto as lojas online mantêm o estado mais recente.
Configuração
Configuração da loja offline
O armazenamento offline é configurado usando MongoDBOfflineStoreConfig:
class MongoDBOfflineStoreConfig(FeastConfigBaseModel): type: str = "...MongoDBOfflineStore" connection_string: str = "mongodb://localhost:27017" database: str = "feast" collection: str = "feature_history"
Exemplo 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 é o DataSource correspondente. Seu name campo se torna o feature_view discriminador armazenado em todos os documento. Para obter opções de configuração completas, consulte a referência da Fonte de Dados do MongoDB nos documentos do Feast.
source = MongoDBSource( name="driver_stats", timestamp_field="event_timestamp", created_timestamp_column="created_at", )
Próximos passos
Siga o Início Rápido do Feast para configurar um armazenamento de recursos local e, em seguida, trocar no MongoDB como um armazenamento online e offline usando os exemplos de configuração nesta página.
Revise a referência da MongoDB Online Store nos documentos do Feast para obter opções de configuração, suporte assíncrono e a array de funcionalidade completa.
Revise a referência do armazenamento offline do MongoDB para obter a configuração do armazenamento offline e a funcionalidade compatível.
Revise a referência da Fonte de Dados MongoDB para obter
MongoDBSourceopções e detalhes de esquema.Aprenda os principais conceitos do Feast, como entidades, visualizações de recursos e materialização, no guia Conceitos de Feast.