Graph Namespacing

Using group_ids to create isolated graph namespaces

Overview

Graphiti supports the concept of graph namespacing through the use of group_id parameters. This feature allows you to create isolated graph environments within the same Graphiti instance, enabling multiple distinct knowledge graphs to coexist without interference.

Graph namespacing is particularly useful for:

  • Multi-tenant applications: Isolate data between different customers or organizations
  • Testing environments: Maintain separate development, testing, and production graphs
  • Domain-specific knowledge: Create specialized graphs for different domains or use cases
  • Team collaboration: Allow different teams to work with their own graph spaces

How Namespacing Works

In Graphiti, every node and edge can be associated with a group_id. When you specify a group_id, you’re effectively creating a namespace for that data. Nodes and edges with the same group_id form a cohesive, isolated graph that can be queried and manipulated independently from other namespaces.

Key Benefits

  • Data isolation: Prevent data leakage between different namespaces
  • Simplified management: Organize and manage related data together
  • Performance optimization: Improve query performance by limiting the search space
  • Flexible architecture: Support multiple use cases within a single Graphiti instance

Using group_ids in Graphiti

Adding Episodes with group_id

When adding episodes to your graph, you can specify a group_id to namespace the episode and all its extracted entities:

1await graphiti.add_episode(
2 name="customer_interaction",
3 episode_body="Customer Jane mentioned she loves our new SuperLight Wool Runners in Dark Grey.",
4 source=EpisodeType.text,
5 source_description="Customer feedback",
6 reference_time=datetime.now(),
7 group_id="customer_team" # This namespaces the episode and its entities
8)

Adding Fact Triples with group_id

When manually adding fact triples, ensure both nodes and the edge share the same group_id:

1from graphiti_core.nodes import EntityNode
2from graphiti_core.edges import EntityEdge
3import uuid
4from datetime import datetime
5
6# Define a namespace for this data
7namespace = "product_catalog"
8
9# Create source and target nodes with the namespace
10source_node = EntityNode(
11 uuid=str(uuid.uuid4()),
12 name="SuperLight Wool Runners",
13 group_id=namespace # Apply namespace to source node
14)
15
16target_node = EntityNode(
17 uuid=str(uuid.uuid4()),
18 name="Sustainable Footwear",
19 group_id=namespace # Apply namespace to target node
20)
21
22# Create an edge with the same namespace
23edge = EntityEdge(
24 group_id=namespace, # Apply namespace to edge
25 source_node_uuid=source_node.uuid,
26 target_node_uuid=target_node.uuid,
27 created_at=datetime.now(),
28 name="is_category_of",
29 fact="SuperLight Wool Runners is a product in the Sustainable Footwear category"
30)
31
32# Add the triplet to the graph
33await graphiti.add_triplet(source_node, edge, target_node)

Querying Within a Namespace

When querying the graph, specify the group_id to limit results to a particular namespace:

1# Search within a specific namespace
2search_results = await graphiti.search(
3 query="Wool Runners",
4 group_id="product_catalog" # Only search within this namespace
5)
6
7# For more advanced node-specific searches, use the _search method with a recipe
8from graphiti_core.search.search_config_recipes import NODE_HYBRID_SEARCH_RRF
9
10# Create a search config for nodes only
11node_search_config = NODE_HYBRID_SEARCH_RRF.model_copy(deep=True)
12node_search_config.limit = 5 # Limit to 5 results
13
14# Execute the node search within a specific namespace
15node_search_results = await graphiti._search(
16 query="SuperLight Wool Runners",
17 group_id="product_catalog", # Only search within this namespace
18 config=node_search_config
19)

Best Practices for Graph Namespacing

  1. Consistent naming: Use a consistent naming convention for your group_id values
  2. Documentation: Maintain documentation of your namespace structure and purpose
  3. Granularity: Choose an appropriate level of granularity for your namespaces
    • Too many namespaces can lead to fragmented data
    • Too few namespaces may not provide sufficient isolation
  4. Cross-namespace queries: When necessary, perform multiple queries across namespaces and combine results in your application logic

Example: Multi-tenant Application

Here’s an example of using namespacing in a multi-tenant application:

1async def add_customer_data(tenant_id, customer_data):
2 """Add customer data to a tenant-specific namespace"""
3
4 # Use the tenant_id as the namespace
5 namespace = f"tenant_{tenant_id}"
6
7 # Create an episode for this customer data
8 await graphiti.add_episode(
9 name=f"customer_data_{customer_data['id']}",
10 episode_body=customer_data,
11 source=EpisodeType.json,
12 source_description="Customer profile update",
13 reference_time=datetime.now(),
14 group_id=namespace # Namespace by tenant
15 )
16
17async def search_tenant_data(tenant_id, query):
18 """Search within a tenant's namespace"""
19
20 namespace = f"tenant_{tenant_id}"
21
22 # Only search within this tenant's namespace
23 return await graphiti.search(
24 query=query,
25 group_id=namespace
26 )