El problema fundamental que LatticeDB aborda es la fragmentación y la complejidad operativa inherente a la gestión de datos interconectados, semánticos y textuales en aplicaciones locales. Tradicionalmente, este tipo de cargas de trabajo (como Graph RAG, memoria de agentes o herramientas de conocimiento local) requerirían la integración de múltiples sistemas de almacenamiento: una base de datos de grafos para las relaciones, un índice vectorial para la similitud semántica y un motor de búsqueda de texto completo para la recuperación léxica. Esta aproximación introduce sobrecarga de sincronización, latencia de red y una complejidad de infraestructura significativa.
LatticeDB propone una solución unificada al consolidar estas tres capacidades de indexación y consulta en un único motor embebido y un solo archivo. Esto simplifica drásticamente el stack tecnológico para desarrolladores de aplicaciones locales, eliminando la necesidad de servidores externos, configuraciones complejas o la gestión de múltiples almacenes de datos. La integración de estas funcionalidades en una capa de consulta cohesiva permite operaciones complejas que combinan traversal de grafos, búsqueda vectorial y filtrado de texto en una sola transacción, lo cual es crucial para escenarios donde la coherencia y el rendimiento son prioritarios en un entorno de máquina única.
Arquitectura del Sistema
LatticeDB se implementa como una base de datos embebida de un solo archivo, escrita en Zig, sin dependencias externas. Su arquitectura se centra en un modelo de escritor único y durabilidad respaldada por un Write-Ahead Log (WAL), garantizando la recuperación ante fallos. El motor de almacenamiento subyacente utiliza B+Trees para las búsquedas de nodos y propiedades, logrando latencias de microsegundos para operaciones básicas.
Para la búsqueda vectorial, LatticeDB integra un índice HNSW (Hierarchical Navigable Small World) para la búsqueda de vecinos más cercanos aproximados (ANN). Este índice es configurable en parámetros como M (número de conexiones salientes por nodo) y ef (tamaño de la lista de candidatos durante la construcción y búsqueda), optimizando el balance entre latencia, recall y uso de memoria. La distancia coseno se calcula eficientemente utilizando productos punto pre-normalizados. La búsqueda de texto completo se implementa con un índice invertido y utiliza el algoritmo BM25 para el ranking de relevancia. La tokenización y el stemming son parte de esta funcionalidad. Todas estas capacidades se exponen a través de una única capa de consulta que soporta un subconjunto del lenguaje Cypher, extendido con operadores para distancia vectorial (<=>) y búsqueda de texto completo (@@). Además, el sistema incluye streams duraderos con offsets de consumidor explícitos y un changefeed de grafos, compartiendo la misma ruta de transacción/WAL que las escrituras de grafos.
Flujo de Ingestión y Consulta de Datos
- 1 Aplicación Cliente Inicia una transacción de escritura en LatticeDB.
- 2 LatticeDB Write Txn Crea nodos, aristas, establece propiedades y vectores.
- 3 HNSW Indexer Actualiza el índice HNSW con nuevos vectores.
- 4 BM25 FTS Indexer Actualiza el índice invertido de texto completo.
- 5 WAL Registra todas las operaciones para durabilidad y recuperación.
- 6 Almacenamiento en Disco Persiste los datos y los índices en un único archivo .db.
- 7 Aplicación Cliente Ejecuta una consulta Cypher combinando grafos, vectores y texto.
- 8 LatticeDB Query Engine Optimiza y ejecuta la consulta utilizando los índices apropiados.
| Capa | Tecnología | Justificación |
|---|---|---|
| storage | B+Tree | Estructura de datos principal para la indexación de nodos, aristas y propiedades, permitiendo búsquedas rápidas. |
| storage | Write-Ahead Log (WAL) | Garantiza la durabilidad de las transacciones y la recuperación ante fallos, registrando todas las escrituras antes de aplicarlas al almacenamiento principal. |
| data-processing | HNSW (Hierarchical Navigable Small World) | Algoritmo de índice para la búsqueda de vecinos más cercanos aproximados (ANN) en espacios vectoriales, optimizado para latencia y recall. M=16, ef_construction=200, ef_search=64 para benchmarks de 1M vectores. |
| data-processing | BM25 | Algoritmo de ranking de relevancia para la búsqueda de texto completo, utilizado sobre un índice invertido. |
| compute | Zig | Lenguaje de programación de bajo nivel utilizado para implementar el motor de la base de datos, permitiendo control de memoria y rendimiento. |
Trade-offs
Ganancias
- ▲ Simplicidad operativa
- ▲ Rendimiento en máquina única
- ▲ Integración de capacidades de búsqueda
- ▲ Bajo footprint de recursos
Costes
- ▲ Escalabilidad horizontal (multi-nodo)
- ▲ Concurrencia de escritura (single-writer)
- ▲ Madurez del ecosistema y tooling
- △ Soporte completo del lenguaje Cypher
from latticedb import Database
from latticedb.embedding import hash_embed
with Database("knowledge.db", create=True, enable_vectors=True, vector_dimensions=128) as db:
with db.write() as txn:
alice = txn.create_node(labels=["Person"], properties={"name": "Alice", "field": "ML"})
doc = txn.create_node(labels=["Document"], properties={"title": "Attention Is All You Need"})
chunk = txn.create_node(labels=["Chunk"], properties={"text": "The transformer architecture uses self-attention..."})
txn.set_vector(chunk.id, "embedding", hash_embed(chunk.properties["text"], dimensions=128))
txn.fts_index(chunk.id, chunk.properties["text"])
txn.create_edge(chunk.id, doc.id, "PART_OF")
txn.create_edge(doc.id, alice.id, "AUTHORED_BY")
txn.commit()results = db.query("""
MATCH (chunk:Chunk)-[:PART_OF]->(doc:Document)-[:AUTHORED_BY]->(author:Person)
WHERE chunk.embedding <=> $query < 0.5
RETURN doc.title, chunk.text, author.name
ORDER BY chunk.embedding <=> $query
LIMIT 5
""", parameters={"query": hash_embed("transformer attention mechanism", dimensions=128)})Fundamentos Teóricos
La integración de múltiples paradigmas de búsqueda en un solo motor evoca principios de sistemas de gestión de bases de datos federadas o políglotas, aunque LatticeDB lo hace a nivel de motor embebido. La base de datos de grafos se apoya en conceptos bien establecidos de teoría de grafos y estructuras de datos para representaciones de adyacencia, similares a las discutidas en trabajos como 'Graph Databases' de Robinson, Webber y Eifrem (2013).
La búsqueda vectorial se basa directamente en el algoritmo HNSW, propuesto por Yury Malkov y Dmitry Yashunin en 'Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs' (2016). Este paper detalla cómo construir un grafo de múltiples capas para acelerar la búsqueda ANN, ofreciendo un excelente balance entre precisión y rendimiento. La búsqueda de texto completo utiliza el algoritmo BM25, un modelo de ranking de relevancia que se remonta a los trabajos de Robertson y Sparck Jones en la década de 1990, siendo una evolución de TF-IDF y un estándar en la recuperación de información. La durabilidad y recuperación ante fallos se basan en el concepto de Write-Ahead Log (WAL), un pilar de los sistemas de bases de datos transaccionales, descrito en detalle en 'Principles of Database Systems' de Ullman y Widom (1997).