Skip to main content
Glama
northernvariables

FedMCP - Federal Parliamentary Information

05-verification-queries.cypher7.8 kB
// ============================================================ // Verification & Performance Testing Queries // ============================================================ // Run these after all optimizations to verify: // 1. All indexes are online // 2. Indexes are being used correctly // 3. Performance improvements are realized // ============================================================ // ============================================================ // 1. Index Health Check // ============================================================ // Show all indexes and their status CALL db.indexes() YIELD name, type, state, populationPercent, lastRead, readCount ORDER BY type, name RETURN type, name, state, populationPercent, lastRead, readCount; // Count indexes by type CALL db.indexes() YIELD type RETURN type, count(*) as count ORDER BY type; // Find any failed or populating indexes CALL db.indexes() YIELD name, state, populationPercent WHERE state <> 'ONLINE' OR populationPercent < 100 RETURN name, state, populationPercent; // ============================================================ // 2. Constraint Verification // ============================================================ // Show all constraints SHOW CONSTRAINTS; // Count constraints by type SHOW CONSTRAINTS YIELD name, type RETURN type, count(*) as count; // ============================================================ // 3. Database Statistics // ============================================================ // Total nodes and relationships MATCH (n) RETURN count(n) as total_nodes; MATCH ()-[r]->() RETURN count(r) as total_relationships; // Nodes by label (top 20) MATCH (n) RETURN labels(n)[0] as label, count(*) as count ORDER BY count DESC LIMIT 20; // Relationships by type (top 20) MATCH ()-[r]->() RETURN type(r) as relationship, count(*) as count ORDER BY count DESC LIMIT 20; // ============================================================ // 4. Performance Testing - BEFORE vs AFTER // ============================================================ // Test 1: MP Lookup by ID // BEFORE optimization: ~50-100ms (label scan) // AFTER optimization: ~1-5ms (constraint index) PROFILE MATCH (m:MP {id: 'pierre-poilievre'}) RETURN m; // Verify: Should show "NodeUniqueIndexSeek" (not NodeByLabelScan) // Test 2: Bill Search with Filter // BEFORE: ~2-5 seconds (full scan) // AFTER: ~50-200ms (range index) PROFILE MATCH (b:Bill) WHERE b.status = 'Passed' AND b.session = '44-1' RETURN b LIMIT 10; // Verify: Should show "NodeIndexSeek" on bill_session_status // Test 3: Full-Text Search // BEFORE: ~10-30 seconds (regex/CONTAINS) // AFTER: ~200-500ms (fulltext index) PROFILE CALL db.index.fulltext.queryNodes('bill_title_search', 'climate change') YIELD node, score RETURN node.title, score ORDER BY score DESC LIMIT 10; // Verify: Should show "NodeIndexFullTextSeek" // Test 4: MP Expenses by Fiscal Year // BEFORE: ~500-1000ms (full expense scan) // AFTER: ~50-100ms (composite index) PROFILE MATCH (e:Expense {mp_id: 'pierre-poilievre', fiscal_year: 2024}) RETURN sum(e.amount) as total; // Verify: Should show "NodeIndexSeek" on mp_fiscal_year // Test 5: Relationship Filtering // BEFORE: ~1-2 seconds (scan all VOTED relationships) // AFTER: ~50-100ms (relationship index) PROFILE MATCH (:MP {id: 'pierre-poilievre'})-[v:VOTED {position: 'yea'}]->(vote:Vote) WHERE vote.date > date('2024-01-01') RETURN count(v); // Verify: Should show "DirectedRelationshipIndexSeek" // ============================================================ // 5. Slow Query Detection // ============================================================ // Find currently running queries taking > 1 second CALL dbms.listQueries() YIELD queryId, elapsedTimeMillis, query, username WHERE elapsedTimeMillis > 1000 RETURN queryId, elapsedTimeMillis, substring(query, 0, 100) as query_preview, username ORDER BY elapsedTimeMillis DESC; // ============================================================ // 6. Index Usage Statistics // ============================================================ // Show which indexes are actually being used CALL db.indexes() YIELD name, type, readCount WHERE readCount > 0 RETURN name, type, readCount ORDER BY readCount DESC LIMIT 20; // Show unused indexes (might need to remove or investigate) CALL db.indexes() YIELD name, type, readCount, lastRead WHERE readCount = 0 OR lastRead IS NULL RETURN name, type, readCount, lastRead ORDER BY name; // ============================================================ // 7. Full-Text Index Testing // ============================================================ // Test bill search CALL db.index.fulltext.queryNodes('bill_title_search', 'climate carbon emissions') YIELD node, score RETURN node.number, node.title, score ORDER BY score DESC LIMIT 5; // Test MP search CALL db.index.fulltext.queryNodes('mp_name_search', 'justin trudeau') YIELD node, score RETURN node.name, node.party, score ORDER BY score DESC LIMIT 5; // Test petition search CALL db.index.fulltext.queryNodes('petition_text_search', 'healthcare funding') YIELD node, score RETURN node.number, node.title, score ORDER BY score DESC LIMIT 5; // ============================================================ // 8. Storage Impact Assessment // ============================================================ // Approximate database size CALL apoc.meta.stats() YIELD nodeCount, relCount, labels, relTypes RETURN nodeCount, relCount, size(keys(labels)) as label_count, size(keys(relTypes)) as rel_type_count; // Note: To see actual disk usage, run this on the Neo4j server: // CALL dbms.queryJmx('org.neo4j:instance=kernel#0,name=Store file sizes') // YIELD attributes // RETURN attributes; // ============================================================ // 9. MCP Query Performance Tests // ============================================================ // Simulate common MCP queries and measure performance // Test: searchMPs by party PROFILE MATCH (m:MP {party: 'Conservative', current: true}) RETURN m.name, m.riding ORDER BY m.name LIMIT 20; // Test: searchBills by keyword (full-text) PROFILE CALL db.index.fulltext.queryNodes('bill_title_search', 'environment protection') YIELD node, score WHERE node.session = '44-1' RETURN node.number, node.title, node.status, score ORDER BY score DESC LIMIT 10; // Test: MP accountability scorecard aggregation PROFILE MATCH (mp:MP {id: 'pierre-poilievre'}) CALL { WITH mp OPTIONAL MATCH (mp)-[:SPONSORED]->(bill:Bill) RETURN count(bill) as bills_sponsored } CALL { WITH mp OPTIONAL MATCH (mp)-[:VOTED]->(vote:Vote) RETURN count(vote) as votes_cast } CALL { WITH mp MATCH (mp)-[:INCURRED]->(expense:Expense {fiscal_year: 2024}) RETURN sum(expense.amount) as total_expenses } RETURN mp.name, bills_sponsored, votes_cast, total_expenses; // Test: Lobbying search PROFILE MATCH (l:LobbyRegistration {active: true}) WHERE l.client_org_name CONTAINS 'Pharmaceutical' RETURN l.client_org_name, l.registrant_name, l.effective_date ORDER BY l.effective_date DESC LIMIT 10; // ============================================================ // Expected Results Summary // ============================================================ // After running all optimization scripts, you should see: // // 1. Constraints: ~20-25 unique constraints // 2. Range Indexes: ~50-60 property indexes // 3. Full-Text Indexes: ~10 text search indexes // 4. All indexes: state = 'ONLINE', populationPercent = 100 // // Performance Improvements: // - ID lookups: 50-100ms → 1-5ms (20-30x faster) // - Filtered queries: 1-5 seconds → 50-200ms (10-50x faster) // - Text searches: 10-30 seconds → 200-500ms (50-100x faster) // - Scorecard aggregations: 500-1000ms → 100-300ms (5-10x faster) // // Total index overhead: ~3-5GB

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/northernvariables/FedMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server