Labeled Meta Property Graphs (LMPG): A Property-Centric Approach to Graph Database Architecture
Discover how LMPG transforms graph databases by treating properties as first-class citizens rather than simple node attributes. This comprehensive technical guide explores RushDB's groundbreaking architecture that enables automatic schema evolution, property-first queries, and cross-domain analytics impossible in traditional property graphs or RDF systems.
RushDB is a self-describing, graph-native database that helps AI agents reason over data with confidence: progressively introspect what's queryable—without guesswork.
In the evolving landscape of database technologies, graph databases have emerged as powerful solutions for managing interconnected data. However, most graph databases still require developers to think in terms of nodes, edges, and complex query languages. RushDB introduces a paradigm shift with its Labeled Meta Property Graph (LMPG) architecture – a revolutionary approach that makes properties first-class citizens and enables unprecedented flexibility in data modeling and querying.
What sets LMPG apart is its unified query interface that allows a single Data Transfer Object (DTO) to query Records, Labels, Properties, Relationships, and Available Values across any subgraph perspective. This creates what we call "database self-awareness" – the ability for the system to introspect and optimize queries dynamically based on the property-centric architecture.
Traditional property graphs, while powerful, force developers into rigid thinking patterns:
Schema-first mindset: You must define your data structure before storing data
Query complexity: Learning Cypher, Gremlin, or other graph query languages
Relationship overhead: Manually defining and maintaining relationships
Type constraints: Rigid type systems that don't adapt to evolving data
Consider a typical e-commerce scenario in a traditional property graph:
cypher
// Traditional approach - you must know the schemaMATCH(product:Product)-[:BELONGS_TO]->(category:Category)WHERE product.price >100AND category.name ='Electronics'RETURN product.name, product.price
RushDB employs a sophisticated Breadth-First Search (BFS) algorithm to automatically convert hierarchical JSON data into LMPG structures. This process eliminates the need for manual schema design while preserving data relationships.
Let's see how RushDB transforms complex JSON into an LMPG:
Input JSON:
JSON
{"products":[{"id":"prod-001","name":"Wireless Headphones","price":299.99,"inStock":true,"category":{"name":"Electronics","department":"Audio"},"specifications":{"batteryLife":"30 hours","connectivity":["Bluetooth 5.0","USB-C"],"weight":250},"reviews":[{"rating":5,"comment":"Excellent sound quality","verified":true},{"rating":4,"comment":"Good value for money","verified":false}]}]}
LMPG Transformation Process:
BFS Level 0 - Root object detection
BFS Level 1 - Extract main entities (product, category, specifications)
// Find all items with price > 1000 across different typesMATCH(n)WHERE(n:Car OR n:House OR n:Jewelry)AND n.price >1000RETURN n.name, n.price,labels(n)
# Same query in RushDB - discover ANY record with price > 1000from rushdb import RushDB
db = RushDB("RUSHDB_API_TOKEN")results = db.records.find({"where":{"price":{"$gt":1000}}})
Advantages:
Automatically finds all records regardless of type
# Add vector embeddings as propertiesdb.records.create({"label":"Document","data":{"title":"AI Research Paper","content":"Large language models have revolutionized...","embedding":[0.1,0.8,-0.3,0.9,...],# 1536-dimensional vector"category":"AI Research","publishDate":"2024-01-15","citationCount":42,"impact_score":8.7}});
Traditional database performance degrades with data size and query complexity. LMPG maintains consistent performance through its revolutionary perforating query architecture that skips expensive operations by leveraging properties as dynamic indices.
1. Property-First Indexing:
Text
Traditional JOIN: O(n × m × log(k))
LMPG Traversal: O(p + r)
Where:
n, m, k = table/node sizes
p = number of properties
r = number of relevant records
2. Perforating Query Execution:
Diagram
3. Dynamic Index Management:
Properties act as living indices that:
Self-organize with controllable overhead
Adapt to data distribution in real-time
4. Handful Index Optimization:
sql
-- Auto-generated Neo4j indexes for each propertyCREATEINDEX property_name_string FOR(n:__RUSHDB__LABEL__PROPERTY__)ON(n.name, n.type, n.projectId, n.metadata);CREATEINDEX record_lookup FOR(n:__RUSHDB__LABEL__RECORD__)ON(n.__RUSHDB__KEY__ID__, n.__RUSHDB__KEY__PROJECT__ID__);
RushDB's revolutionary graph perforating architecture achieves unprecedented data observability through a single unified query interface. Unlike traditional databases that require separate APIs for different data perspectives, LMPG enables one query to simultaneously access Records, Labels, Properties, Values, and Relationships.
# Get actual department records matching criteriarecords = db.records.find(QUERY)
Generated Cypher Query:
cypher
MATCH(record:__RUSHDB__LABEL__RECORD__:`DEPARTMENT`{ __RUSHDB__KEY__PROJECT__ID__:$projectId})WHERE(any(value IN record.name WHERE value =~"(?i).*e.*"))OPTIONALMATCH(record)--(record1:PROJECT)WHERE((any(value IN record1.budget WHERE value <=10000000)XORany(value IN record1.budget WHERE value >=15000000)))OPTIONALMATCH(record1)--(record2:EMPLOYEE)WHERE(any(value IN record2.salary WHERE value >=300000))WITH record, record1, record2
WHERE record ISNOTNULLAND(record1 ISNOTNULLAND record2 ISNOTNULL)RETURN record
SKIP0LIMIT1000
Resulting Data:
JSON
{"data":[{"__id":"01974151-41f4-7c7e-a9bd-a28df7703077","__label":"DEPARTMENT","name":"Research and Development","description":"Innovation-focused department driving product evolution","headcount":150,"budget":2500000}],"total":5,"success":true}
# Discover all entity types matching the criterialabels = db.labels.find(QUERY)
Generated Cypher Query:
cypher
MATCH(record:__RUSHDB__LABEL__RECORD__{ __RUSHDB__KEY__PROJECT__ID__:$projectId})WHERE(any(value IN record.name WHERE value =~"(?i).*e.*"))OPTIONALMATCH(record)--(record1:PROJECT)WHERE((any(value IN record1.budget WHERE value <=10000000)XORany(value IN record1.budget WHERE value >=15000000)))OPTIONALMATCH(record1)--(record2:EMPLOYEE)WHERE(any(value IN record2.salary WHERE value >=300000))WITH record, record1, record2
WHERE record ISNOTNULLAND(record1 ISNOTNULLAND record2 ISNOTNULL)WITHDISTINCT record,[label INlabels(record)WHERE label <>"__RUSHDB__LABEL__RECORD__"]as recordLabels
RETURNcount(recordLabels)as total, recordLabels[0]as label
# Discover available properties across matching entitiesproperties = db.properties.find(QUERY)
Generated Cypher Queries:
cypher
-- Get entity-specific properties
MATCH(record:__RUSHDB__LABEL__RECORD__:`DEPARTMENT`{ __RUSHDB__KEY__PROJECT__ID__:$projectId})WHERE(any(value IN record.name WHERE value =~"(?i).*e.*"))OPTIONALMATCH(record)--(record1:PROJECT)WHERE((any(value IN record1.budget WHERE value <=10000000)XORany(value IN record1.budget WHERE value >=15000000)))OPTIONALMATCH(record1)--(record2:EMPLOYEE)WHERE(any(value IN record2.salary WHERE value >=300000))WITH record, record1, record2
WHERE record ISNOTNULLAND(record1 ISNOTNULLAND record2 ISNOTNULL)UNWINDkeys(record)as propertyName
RETURNcollect(DISTINCT propertyName)as fields
-- Get global property metadata
MATCH(property:__RUSHDB__LABEL__PROPERTY__{ projectId:$id})RETURNcollect(DISTINCT property {.id,.metadata,.name,.type,.projectId })as properties
# Get distinct values and ranges for specific propertiesvalues = db.properties.values(property_id, QUERY)
Generated Cypher Query:
cypher
MATCH(record:__RUSHDB__LABEL__RECORD__:`DEPARTMENT`{ __RUSHDB__KEY__PROJECT__ID__:$projectId})<-[value:__RUSHDB__RELATION__VALUE__]-(property:__RUSHDB__LABEL__PROPERTY__{ id:$id})WHERE(any(value IN record.name WHERE value =~"(?i).*e.*"))OPTIONALMATCH(record)--(record1:PROJECT)WHERE((any(value IN record1.budget WHERE value <=10000000)XORany(value IN record1.budget WHERE value >=15000000)))OPTIONALMATCH(record1)--(record2:EMPLOYEE)WHERE(any(value IN record2.salary WHERE value >=300000))AND record[property.name]ISNOTNULLAND property.type <>'vector'WITH property, record, record1, record2
WHERE record ISNOTNULLAND(record1 ISNOTNULLAND record2 ISNOTNULL)WITH record[property.name]AS propValue, property.type AS propType
ORDERBY record.__RUSHDB__KEY__ID__
WITH apoc.coll.toSet(apoc.coll.flatten(collect(DISTINCT propValue)))AS values, propType as type
UNWIND values AS v
WITH values, type,min(CASE type WHEN'datetime'THENdatetime(v)ELSEtoFloatOrNull(v)END)AS minValue,max(CASE type WHEN'datetime'THENdatetime(v)ELSEtoFloatOrNull(v)END)AS maxValue
RETURN{ values: values[0..1000], min:CASE type WHEN'datetime'THENtoString(minValue)ELSE minValue END, max:CASE type WHEN'datetime'THENtoString(maxValue)ELSE maxValue END, type: type
}AS result
Resulting Data:
JSON
{"data":{"values":["Research and Development","Engineering Excellence Division","Product Innovation Center","Advanced Technology Department","Strategic Development Unit"],"min":null,"max":null,"type":"string"},"success":true}
# Discover relationships between matching entitiesrelationships = db.relationships.find(QUERY)
Generated Cypher Queries:
cypher
-- Get relationship details
MATCH(record:__RUSHDB__LABEL__RECORD__:`DEPARTMENT`{ __RUSHDB__KEY__PROJECT__ID__:$projectId})WHERE(any(value IN record.name WHERE value =~"(?i).*e.*"))OPTIONALMATCH(record)--(record1:PROJECT)WHERE((any(value IN record1.budget WHERE value <=10000000)XORany(value IN record1.budget WHERE value >=15000000)))OPTIONALMATCH(record1)--(record2:EMPLOYEE)WHERE(any(value IN record2.salary WHERE value >=300000))WITH record, record1, record2
WHERE record ISNOTNULLAND(record1 ISNOTNULLAND record2 ISNOTNULL)MATCH(record)-[rel]-(neighbor:__RUSHDB__LABEL__RECORD__)SKIP0LIMIT1000RETURNDISTINCTCASEWHENstartNode(rel)= record THEN{ sourceId: record.__RUSHDB__KEY__ID__, sourceLabel:[label INlabels(record)WHERE label <>"__RUSHDB__LABEL__RECORD__"][0], targetId: neighbor.__RUSHDB__KEY__ID__, targetLabel:[label INlabels(neighbor)WHERE label <>"__RUSHDB__LABEL__RECORD__"][0], type:type(rel)}ELSE{ sourceId: neighbor.__RUSHDB__KEY__ID__, sourceLabel:[label INlabels(neighbor)WHERE label <>"__RUSHDB__LABEL__RECORD__"][0], targetId: record.__RUSHDB__KEY__ID__, targetLabel:[label INlabels(record)WHERE label <>"__RUSHDB__LABEL__RECORD__"][0], type:type(rel)}ENDAS relation
-- Get relationship count
MATCH(record:__RUSHDB__LABEL__RECORD__:`DEPARTMENT`{ __RUSHDB__KEY__PROJECT__ID__:$projectId})WHERE(any(value IN record.name WHERE value =~"(?i).*e.*"))OPTIONALMATCH(record)--(record1:PROJECT)WHERE((any(value IN record1.budget WHERE value <=10000000)XORany(value IN record1.budget WHERE value >=15000000)))OPTIONALMATCH(record1)--(record2:EMPLOYEE)WHERE(any(value IN record2.salary WHERE value >=300000))WITH record, record1, record2
WHERE record ISNOTNULLAND(record1 ISNOTNULLAND record2 ISNOTNULL)MATCH(record)-[rel]-(target:__RUSHDB__LABEL__RECORD__)RETURNcount(DISTINCT rel)as total
The key insight is that RushDB's property-centric architecture allows the same filtered record set to be analyzed from multiple perspectives without re-executing the expensive traversal logic. The WHERE clauses are shared across all perspective queries, enabling massive optimization through result set reuse.
The most transformative aspect of LMPG is its unified query interface that eliminates the complexity of traditional database interactions:
Diagram
Key Benefits of the Unified Interface:
Single DTO, infinite perspectives: One query interface for all data aspects
Properties as dynamic indices: Self-optimizing performance without manual tuning
Database self-awareness: Automatic adaptation to data patterns and usage
Perforating query architecture: Skip expensive operations for consistent performance
Cross-domain insights: Discover relationships across unrelated data domains
This revolutionary approach means developers no longer need to learn separate APIs for different database operations. Whether you need records, schema information, property metadata, value ranges, or relationship mappings - it all comes from the same intuitive JSON query structure demonstrated in the Graph Perforating section above.
The unified query interface opens up entirely new possibilities across multiple domains, enabling sophisticated applications without writing complex database code:
1. Cataloging Indeterminate Data
Challenge: Scientific datasets, IoT streams, and user-generated content often have unpredictable schemas and evolving structures.
LMPG Solution: Automatic schema adaptation with unified querying across all data perspectives.
# Automatically catalog any scientific data structureresearch_data = db.records.create({"label":"Experiment","data":{"experiment_id":"EXP-2024-001","temperature":23.5,"unexpected_compound":"C8H10N4O2",# New discovery"readings":[1.2,3.4,5.6],"metadata":{"researcher":"Dr. Smith","equipment":"Spectrometer-X200"}}})# Later, discover all experiments with any temperature datatemperature_studies = db.records.find({"where":{"temperature":{"$exists":True}}})# Automatically discover new property typesnew_properties = db.properties.find()# Finds "unexpected_compound" propertyproperty_values = db.properties.values(compound_property_id)# Get all compound values
Result: Zero-configuration data cataloging that automatically adapts to new discoveries.
2. AI-Driven Scientific Research Loops
Challenge: Modern AI research requires iterative data exploration, hypothesis generation, and validation across evolving datasets.
LMPG Solution: Unified interface enables AI agents to autonomously explore data relationships and generate research hypotheses.
# AI research agent workflowclassResearchAgent:defexplore_correlations(self):# Discover all numeric properties numeric_props = db.properties.find({"where":{"type":"number"}})for prop in numeric_props["data"]:# Get value distributions distribution = db.properties.values(prop["id"])# Find correlating entities correlated_records = db.records.find({"where":{prop["name"]:{"$gte": distribution["data"]["min"]}}})# Discover relationship patterns relationships = db.relationships.find(correlated_records["query"])# Generate hypothesis based on discovered patternsyield self.generate_hypothesis(prop, distribution, relationships)defvalidate_hypothesis(self, hypothesis):# Use unified interface to test hypothesis across all data perspectives validation_query ={"where": hypothesis["conditions"]} results ={"records": db.records.find(validation_query),"patterns": db.relationships.find(validation_query),"distributions":[db.properties.values(p)for p in hypothesis["properties"]]}return self.analyze_validation(results)
Result: AI agents can autonomously discover patterns, generate hypotheses, and validate theories through iterative data exploration.
3. Unbeatable E-commerce Filtering (Zero Code)
Challenge: Building sophisticated product filtering requires complex database queries and extensive frontend logic.
LMPG Solution: Unified interface automatically generates filters from data, requires zero manual configuration.
# Auto-generate complete filtering interfaceclassAutoFilter:def__init__(self, category="Product"): self.category = category
defget_filter_options(self):# Single query gets all filter possibilities base_query ={"labels":[self.category]}return{# Available products"products": db.records.find(base_query),# Auto-discovered filter categories"categories": db.labels.find(base_query),# All filterable properties"properties": db.properties.find(base_query),# Value ranges for each property"ranges":{ prop["name"]: db.properties.values(prop["id"], base_query)for prop in db.properties.find(base_query)["data"]}}defapply_filters(self, user_filters):# User filters automatically become query conditions filtered_query ={"labels":[self.category],"where": user_filters # Direct mapping from UI}return{"products": db.records.find(filtered_query),"updated_ranges": self.get_updated_ranges(filtered_query),"related_categories": db.labels.find(filtered_query)}# Frontend automatically adapts to any product catalogauto_filter = AutoFilter("Product")filter_ui = auto_filter.get_filter_options()# User applies filters - no backend code neededuser_selection ={"price":{"$gte":100,"$lte":500},"rating":{"$gte":4.0},"brand":{"$in":["Nike","Adidas"]},"CATEGORY":{"trending":True}}filtered_results = auto_filter.apply_filters(user_selection)
Result: Complete e-commerce filtering interface that automatically adapts to any product catalog without writing filtering logic.
4. Real-Time Analytical Workloads
Challenge: Traditional analytical queries require complex aggregations, joins, and pre-computed views.
LMPG Solution: Unified interface enables real-time analytics across any data dimension without pre-configuration.
# Real-time business intelligence dashboardclassRealTimeAnalytics:def__init__(self): self.metrics ={}defget_sales_insights(self, time_range): base_query ={"labels":["Sale"],"where":{"timestamp":{"$gte": time_range["start"],"$lte": time_range["end"]}}}# Single unified call gets all analyticsreturn{# Core sales data"sales": db.records.find(base_query),# Auto-discovered segments"segments": db.labels.find(base_query),# All sales dimensions"dimensions": db.properties.find(base_query),# Value distributions per dimension"distributions":{"revenue": db.properties.values("revenue", base_query),"products": db.properties.values("product_id", base_query),"regions": db.properties.values("region", base_query),"channels": db.properties.values("channel", base_query)},# Relationship insights"correlations": db.relationships.find(base_query)}defdrill_down(self, dimension, value):# Dynamic drill-down without predefined hierarchies drill_query ={"where":{ dimension: value,"timestamp":{"$gte":"2024-01-01"}}}return{"details": db.records.find(drill_query),"related_dimensions": db.properties.find(drill_query),"cross_correlations": db.relationships.find(drill_query)}# Usage: Real-time dashboard that adapts to any businessanalytics = RealTimeAnalytics()# Get comprehensive sales insightsinsights = analytics.get_sales_insights({"start":"2024-01-01","end":"2024-12-31"})# Dynamic drill-down based on user clicksregion_details = analytics.drill_down("region","North America")product_details = analytics.drill_down("product_category","Electronics")
Result: Real-time analytics dashboards that automatically discover and visualize any business dimension without pre-configuration.
5. Healthcare Data Integration
Challenge: Medical data comes from disparate systems with different schemas and requires complex integration.
LMPG Solution: Automatic schema harmonization enables unified patient views across all medical systems.
# Unified patient data across all medical systemsclassMedicalDataIntegration:defintegrate_patient_data(self, patient_id):# Query across all medical record types base_query ={"where":{"patient_id": patient_id
}}return{# All medical records"records": db.records.find(base_query),# Auto-discovered record types"record_types": db.labels.find(base_query),# All medical properties"medical_fields": db.properties.find(base_query),# Value ranges for medical metrics"vital_ranges":{ field["name"]: db.properties.values(field["id"], base_query)for field in db.properties.find(base_query)["data"]if field["name"]in["blood_pressure","heart_rate","temperature"]},# Medical relationships"care_relationships": db.relationships.find(base_query)}deffind_similar_cases(self, symptoms, demographics):# Cross-system case similarity without predefined schemas similarity_query ={"where":{**symptoms,# Any symptom properties**demographics,# Any demographic properties}}return{"similar_patients": db.records.find(similarity_query),"common_patterns": db.relationships.find(similarity_query),"outcome_distributions": db.properties.values("outcome", similarity_query)}# Usage: Instant integration across any medical systemmedical = MedicalDataIntegration()# Complete patient view from all systemspatient_data = medical.integrate_patient_data("PAT-12345")# Find similar cases for treatment planningsimilar_cases = medical.find_similar_cases( symptoms={"chest_pain":True,"shortness_of_breath":True}, demographics={"age":{"$between":[45,65]},"gender":"male"})
Result: Unified patient views and intelligent case matching across any medical system without manual integration work.
These examples demonstrate how LMPG's unified query interface eliminates the complexity barrier that typically prevents sophisticated data applications. Developers can now build AI-driven research tools, zero-code filtering interfaces, real-time analytics, and cross-system integrations using the same simple JSON query structure, enabling unprecedented innovation across all domains.
SELECT p.name, p.price, c.name as category
FROM products p
JOIN categories c ON p.category_id = c.id
JOIN product_attributes pa ON p.id = pa.product_id
JOIN attributes a ON pa.attribute_id = a.id
WHERE p.price >100AND a.name ='color'AND pa.value='red';
The Labeled Meta Property Graph represents a fundamental shift toward property-centric data modeling. As data becomes increasingly interconnected and diverse, LMPG's ability to:
Automatically discover relationships through shared properties
Adapt to evolving schemas without migration overhead
Enable cross-domain insights through property traversal
Simplify complex queries with intuitive JSON syntax
Integrate vector operations for AI-powered applications
Provide unified query interface across all data perspectives
Self-optimize through property-based indexing for massive scale
...makes it the ideal architecture for the next generation of data-intensive applications.
# Push any JSON - LMPG structure is created automaticallyfrom rushdb import RushDB
db = RushDB('your-api-key')customer_data = db.records.create_many({"label":"Customer","data":[{"name":"Alice Johnson","email":"alice@example.com","preferences":{"color":"blue","priceRange":"premium"},"orders":[{"product":"Laptop","amount":1299},{"product":"Mouse","amount":79}]}]})# Query across all automatically-created relationshipspremium_customers = db.records.find({"labels":["Customer"],"where":{"preferences":{"priceRange":"premium",},"orders":{"amount":{"$gt":1000}}}})
RushDB's Labeled Meta Property Graph architecture represents a paradigm shift in database design. By making properties first-class citizens, LMPG enables:
Zero-configuration data modeling with automatic schema inference
Automatic relationship discovery through property overlap analysis
Cross-domain query capabilities with unified interface
Simplified development workflows using intuitive JSON syntax
AI-ready data structures with native vector support
Database self-awareness through dynamic property indexing
Perforating query performance that skips expensive operations
Multi-perspective data access from single query interface
The future of databases is not about forcing data into predefined structures, but about letting the data define its own relationships while providing intelligent optimization. LMPG makes this vision a reality, enabling developers to focus on building features rather than fighting with database schemas.
As applications become increasingly complex and data sources multiply, LMPG's property-centric approach will become the standard for managing interconnected data at scale. The question isn't whether to adopt this architecture – it's how quickly you can start leveraging its power for your applications.
Key Takeaways:
Single DTO, infinite perspectives: One query interface for all data aspects
Properties as dynamic indices: Self-optimizing performance without manual tuning
Database self-awareness: Automatic adaptation to data patterns and usage
Perforating query architecture: Skip expensive operations for consistent performance
Cross-domain insights: Discover relationships across unrelated data domains