Query Knowledge Graph

Observable: Query Knowledge Graph

User Intent

"I want to explore entity relationships and visualize my knowledge graph"

Operation

  • SDK Method: graphlit.queryContentsGraph()

  • GraphQL: queryContentsGraph query

  • Entity Type: Content/Observable (graph relationships)

  • Common Use Cases: Visualize knowledge graphs, explore entity relationships, discover connections, graph analytics

TypeScript (Canonical)

import { Graphlit } from 'graphlit-client';
import { ObservableTypes } from 'graphlit-client/dist/generated/graphql-types';

const graphlit = new Graphlit();

// Query knowledge graph for specific content
const graphResponse = await graphlit.queryContentsGraph({
  contents: [{ id: contentId }]
});

console.log('Knowledge Graph:');
console.log(`Nodes: ${graphResponse.graph.nodes?.length || 0}`);
console.log(`Edges: ${graphResponse.graph.edges?.length || 0}`);

// Access nodes (entities)
graphResponse.graph.nodes?.forEach(node => {
  console.log(`\n${node.type}: ${node.name}`);
  if (node.description) {
    console.log(`  Description: ${node.description}`);
  }
});

// Access edges (relationships)
graphResponse.graph.edges?.forEach(edge => {
  const from = graphResponse.graph.nodes?.find(n => n.id === edge.from);
  const to = graphResponse.graph.nodes?.find(n => n.id === edge.to);
  console.log(`${from?.name}${edge.type}${to?.name}`);
});

// Query graph across all content
const fullGraph = await graphlit.queryContentsGraph();

console.log(`\nFull knowledge graph:`);
console.log(`Total entities: ${fullGraph.graph.nodes?.length || 0}`);
console.log(`Total relationships: ${fullGraph.graph.edges?.length || 0}`);

Query knowledge graph (snake_case)

graph_response = await graphlit.queryContentsGraph( filter=ContentFilterInput( contents=[EntityReferenceFilterInput(id=content_id)] ) )

print(f"Nodes: {len(graph_response.graph.nodes or [])}") print(f"Edges: {len(graph_response.graph.edges or [])}")

Access nodes

for node in (graph_response.graph.nodes or []): print(f"{node.type}: {node.name}")

Access edges

for edge in (graph_response.graph.edges or []): print(f"Relationship: {edge.from_name} → {edge.type} → {edge.to_name}")


**C#**:
```csharp
using Graphlit;

var client = new Graphlit();

// Query knowledge graph (PascalCase)
var graphResponse = await graphlit.QueryContentsGraph(new ContentFilter {
    Contents = new[] { new EntityReferenceFilter { Id = contentId } }
});

Console.WriteLine($"Nodes: {graphResponse.Graph.Nodes?.Count ?? 0}");
Console.WriteLine($"Edges: {graphResponse.Graph.Edges?.Count ?? 0}");

// Access nodes
foreach (var node in graphResponse.Graph.Nodes ?? new List<Node>())
{
    Console.WriteLine($"{node.Type}: {node.Name}");
}

// Access edges
foreach (var edge in graphResponse.Graph.Edges ?? new List<Edge>())
{
    Console.WriteLine($"{edge.From} → {edge.Type} → {edge.To}");
}

Parameters

ContentFilter (Optional)

  • contents (EntityReferenceFilter[]): Filter by specific content

    • Query graph for specific documents

  • collections (EntityReferenceFilter[]): Filter by collection

  • observableTypes (ObservableTypes[]): Filter by entity types

    • PERSON, ORGANIZATION, PLACE, etc.

Response

{
  graph: {
    nodes: GraphNode[];  // Entities
    edges: GraphEdge[];  // Relationships
  }
}

interface GraphNode {
  id: string;              // Entity ID
  name: string;            // Entity name
  type: ObservableType;    // Entity type
  description?: string;    // Entity description
}

interface GraphEdge {
  from: string;            // Source entity ID
  to: string;              // Target entity ID
  type: string;            // Relationship type
  weight?: number;         // Relationship strength
}

Developer Hints

Graph Must Be Built First

Important: Knowledge graph requires content with extraction workflow.

// 1. Create extraction workflow
const workflow = await graphlit.createWorkflow({
  name: 'Entity Extraction',
  extraction: {
    jobs: [{
      connector: {
        type: EntityExtractionServiceTypes.ModelText,
        modelText: {
          specification: { id: extractionSpecId }
        }
      }
    }]
  }
});

// 2. Ingest with extraction
await graphlit.ingestUri(
  uri, undefined, undefined, undefined, true,
  { id: workflow.createWorkflow.id }
);

// 3. Now query graph
const graph = await graphlit.queryContentsGraph();

Filter by Content

// Graph for specific document
const docGraph = await graphlit.queryContentsGraph({
  contents: [{ id: contentId }]
});

// Graph for collection
const collectionGraph = await graphlit.queryContentsGraph({
  collections: [{ id: collectionId }]
});

// Entire knowledge graph
const fullGraph = await graphlit.queryContentsGraph();

Analyze Relationships

const graph = await graphlit.queryContentsGraph();

// Find most connected entities
const connectionCount = new Map<string, number>();

graph.graph.edges?.forEach(edge => {
  connectionCount.set(edge.from, (connectionCount.get(edge.from) || 0) + 1);
  connectionCount.set(edge.to, (connectionCount.get(edge.to) || 0) + 1);
});

// Sort by connections
const sorted = Array.from(connectionCount.entries())
  .sort((a, b) => b[1] - a[1])
  .slice(0, 10);

console.log('Top 10 most connected entities:');
sorted.forEach(([nodeId, count]) => {
  const node = graph.graph.nodes?.find(n => n.id === nodeId);
  console.log(`${node?.name}: ${count} connections`);
});

Visualize Graph

// Export to visualization format (e.g., vis.js, d3.js)
function exportGraphForVisualization(graph: any) {
  const nodes = graph.graph.nodes?.map(node => ({
    id: node.id,
    label: node.name,
    title: node.description,
    group: node.type
  }));
  
  const edges = graph.graph.edges?.map(edge => ({
    from: edge.from,
    to: edge.to,
    label: edge.type,
    value: edge.weight
  }));
  
  return { nodes, edges };
}

const graph = await graphlit.queryContentsGraph();
const vizData = exportGraphForVisualization(graph);

// Use with visualization library
console.log(JSON.stringify(vizData, null, 2));

Variations

1. Query Full Knowledge Graph

Get entire graph:

const graph = await graphlit.queryContentsGraph();

console.log(`Knowledge Graph:`);
console.log(`- Entities: ${graph.graph.nodes?.length || 0}`);
console.log(`- Relationships: ${graph.graph.edges?.length || 0}`);

2. Graph for Specific Document

Single document graph:

const docGraph = await graphlit.queryContentsGraph({
  contents: [{ id: contentId }]
});

console.log(`Document entities: ${docGraph.graph.nodes?.length || 0}`);

3. Graph by Entity Type

Filter by entity types:

const peopleGraph = await graphlit.queryContentsGraph({
  observableTypes: [
    ObservableTypes.Person,
    ObservableTypes.Organization
  ]
});

console.log('People and Organizations network');

4. Collection Knowledge Graph

Graph for collection:

const collectionGraph = await graphlit.queryContentsGraph({
  collections: [{ id: collectionId }]
});

console.log(`Collection graph:`);
console.log(`- Entities: ${collectionGraph.graph.nodes?.length || 0}`);
console.log(`- Relationships: ${collectionGraph.graph.edges?.length || 0}`);

5. Find Entity Connections

Explore specific entity relationships:

const graph = await graphlit.queryContentsGraph();

// Find entity by name
const targetEntity = graph.graph.nodes?.find(
  n => n.name.includes('Microsoft')
);

if (targetEntity) {
  // Find all connections
  const connections = graph.graph.edges?.filter(
    e => e.from === targetEntity.id || e.to === targetEntity.id
  );
  
  console.log(`${targetEntity.name} has ${connections?.length || 0} connections`);
  
  connections?.forEach(edge => {
    const other = graph.graph.nodes?.find(
      n => n.id === (edge.from === targetEntity.id ? edge.to : edge.from)
    );
    console.log(`- ${edge.type}: ${other?.name}`);
  });
}

6. Graph Analytics

Analyze graph structure:

const graph = await graphlit.queryContentsGraph();

// Count by entity type
const typeCounts = graph.graph.nodes?.reduce((acc, node) => {
  acc[node.type] = (acc[node.type] || 0) + 1;
  return acc;
}, {} as Record<string, number>);

console.log('Entity Distribution:');
Object.entries(typeCounts || {}).forEach(([type, count]) => {
  console.log(`  ${type}: ${count}`);
});

// Relationship type distribution
const edgeTypes = graph.graph.edges?.reduce((acc, edge) => {
  acc[edge.type] = (acc[edge.type] || 0) + 1;
  return acc;
}, {} as Record<string, number>);

console.log('\nRelationship Types:');
Object.entries(edgeTypes || {}).forEach(([type, count]) => {
  console.log(`  ${type}: ${count}`);
});

Common Issues

Issue: Empty graph returned Solution: Ensure content was ingested with extraction workflow. Check entities were actually extracted.

Issue: No relationships/edges Solution: Relationships are automatically inferred from co-occurrence and context. More content = more relationships.

Issue: Graph too large to visualize Solution: Filter by specific content or collections. Use entity type filters to reduce scope.

Issue: Missing expected entities Solution: Check extraction workflow configuration. Try better extraction model (Claude Sonnet 3.7).

Production Example

Knowledge graph visualization pipeline:

// 1. Query knowledge graph
const graph = await graphlit.queryContentsGraph({
  collections: [{ id: collectionId }]
});

console.log('=== KNOWLEDGE GRAPH ANALYSIS ===\n');

// 2. Analyze graph structure
const nodeCount = graph.graph.nodes?.length || 0;
const edgeCount = graph.graph.edges?.length || 0;

console.log(`Total Entities: ${nodeCount}`);
console.log(`Total Relationships: ${edgeCount}`);
console.log(`Average Connections: ${(edgeCount / nodeCount * 2).toFixed(2)}\n`);

// 3. Find central entities (most connected)
const connectionCount = new Map<string, number>();

graph.graph.edges?.forEach(edge => {
  connectionCount.set(edge.from, (connectionCount.get(edge.from) || 0) + 1);
  connectionCount.set(edge.to, (connectionCount.get(edge.to) || 0) + 1);
});

const topEntities = Array.from(connectionCount.entries())
  .sort((a, b) => b[1] - a[1])
  .slice(0, 10);

console.log('Top 10 Central Entities:');
topEntities.forEach(([nodeId, count]) => {
  const node = graph.graph.nodes?.find(n => n.id === nodeId);
  console.log(`  ${count} connections: ${node?.name} (${node?.type})`);
});

// 4. Export for visualization
const vizData = {
  nodes: graph.graph.nodes?.map(node => ({
    id: node.id,
    label: node.name,
    title: node.description || node.name,
    group: node.type,
    value: connectionCount.get(node.id) || 1
  })),
  edges: graph.graph.edges?.map(edge => ({
    from: edge.from,
    to: edge.to,
    label: edge.type,
    value: edge.weight || 1
  }))
};

// Save for visualization tool
console.log('\nGraph exported for visualization');
// Use with vis.js, d3.js, Cytoscape.js, etc.

Entity relationship explorer:

// Find relationships for specific entity
async function exploreEntityRelationships(entityName: string) {
  const graph = await graphlit.queryContentsGraph();
  
  // Find entity
  const entity = graph.graph.nodes?.find(
    n => n.name.toLowerCase().includes(entityName.toLowerCase())
  );
  
  if (!entity) {
    console.log(`Entity "${entityName}" not found`);
    return;
  }
  
  console.log(`\n=== ${entity.name} (${entity.type}) ===`);
  if (entity.description) {
    console.log(`Description: ${entity.description}`);
  }
  
  // Find all relationships
  const outgoing = graph.graph.edges?.filter(e => e.from === entity.id) || [];
  const incoming = graph.graph.edges?.filter(e => e.to === entity.id) || [];
  
  console.log(`\nOutgoing Relationships (${outgoing.length}):`);
  outgoing.forEach(edge => {
    const target = graph.graph.nodes?.find(n => n.id === edge.to);
    console.log(`  ${edge.type} → ${target?.name} (${target?.type})`);
  });
  
  console.log(`\nIncoming Relationships (${incoming.length}):`);
  incoming.forEach(edge => {
    const source = graph.graph.nodes?.find(n => n.id === edge.from);
    console.log(`  ${source?.name} (${source?.type}) → ${edge.type}`);
  });
}

// Usage
await exploreEntityRelationships('Microsoft');
await exploreEntityRelationships('John Smith');

Last updated

Was this helpful?