Elasticsearch Knowledge Graph for MCP

by j3k0
  • tests
import { KnowledgeGraphClient } from '../src/kg-client.js'; import { createTestKGClient, setupTestData, cleanupTestData, TEST_ZONE_A } from './test-config.js'; import { ESSearchParams } from '../src/es-types.js'; describe('Boolean Search Functionality', () => { let client: KnowledgeGraphClient; beforeAll(async () => { client = createTestKGClient(); await client.initialize(); await cleanupTestData(client); // Create specific entities for boolean search testing await client.saveEntity({ name: 'BooleanTest1', entityType: 'test', observations: ['This entity contains apple and banana'], relevanceScore: 1.0 }, TEST_ZONE_A); await client.saveEntity({ name: 'BooleanTest2', entityType: 'test', observations: ['This entity contains apple but not banana'], relevanceScore: 1.0 }, TEST_ZONE_A); await client.saveEntity({ name: 'BooleanTest3', entityType: 'test', observations: ['This entity contains banana but not apple'], relevanceScore: 1.0 }, TEST_ZONE_A); await client.saveEntity({ name: 'BooleanTest4', entityType: 'test', observations: ['This entity contains neither apple nor banana'], relevanceScore: 1.0 }, TEST_ZONE_A); }); afterAll(async () => { await cleanupTestData(client); }); test('AND operator should return results with all terms', async () => { const searchParams: ESSearchParams = { query: 'apple AND banana', zone: TEST_ZONE_A }; const result = await client.search(searchParams); // Only BooleanTest1 should match both terms expect(result.hits.hits.length).toBeGreaterThanOrEqual(1); // Extract entity names from the results const entityNames = result.hits.hits .filter(hit => hit._source.type === 'entity') .map(hit => (hit._source as any).name); // Check that BooleanTest1, which has both terms, is included expect(entityNames).toContain('BooleanTest1'); // Check that others are not included expect(entityNames).not.toContain('BooleanTest2'); // has apple but not banana expect(entityNames).not.toContain('BooleanTest3'); // has banana but not apple expect(entityNames).not.toContain('BooleanTest4'); // has neither }); test('OR operator should return results with any of the terms', async () => { const searchParams: ESSearchParams = { query: 'apple OR banana', zone: TEST_ZONE_A }; const result = await client.search(searchParams); // BooleanTest1, BooleanTest2, and BooleanTest3 should match expect(result.hits.hits.length).toBeGreaterThanOrEqual(3); // Extract entity names from the results const entityNames = result.hits.hits .filter(hit => hit._source.type === 'entity') .map(hit => (hit._source as any).name); // Check that entities with either term are included expect(entityNames).toContain('BooleanTest1'); // has both expect(entityNames).toContain('BooleanTest2'); // has apple expect(entityNames).toContain('BooleanTest3'); // has banana // Check that the entity with neither term is not included expect(entityNames).not.toContain('BooleanTest4'); // has neither }); test('NOT operator should exclude results with specified terms', async () => { const searchParams: ESSearchParams = { query: 'apple NOT banana', zone: TEST_ZONE_A }; const result = await client.search(searchParams); // Only BooleanTest2 should match (has apple but not banana) expect(result.hits.hits.length).toBeGreaterThanOrEqual(1); // Extract entity names from the results const entityNames = result.hits.hits .filter(hit => hit._source.type === 'entity') .map(hit => (hit._source as any).name); // Check that only BooleanTest2 is included expect(entityNames).toContain('BooleanTest2'); // Check that others are not included expect(entityNames).not.toContain('BooleanTest1'); // has both expect(entityNames).not.toContain('BooleanTest3'); // has banana but not apple expect(entityNames).not.toContain('BooleanTest4'); // has neither }); test('Complex boolean query should work correctly', async () => { const searchParams: ESSearchParams = { query: '(apple OR banana) AND NOT (apple AND banana)', zone: TEST_ZONE_A }; const result = await client.search(searchParams); // Only BooleanTest2 and BooleanTest3 should match expect(result.hits.hits.length).toBeGreaterThanOrEqual(2); // Extract entity names from the results const entityNames = result.hits.hits .filter(hit => hit._source.type === 'entity') .map(hit => (hit._source as any).name); // Check that only BooleanTest2 and BooleanTest3 are included expect(entityNames).toContain('BooleanTest2'); // has apple but not banana expect(entityNames).toContain('BooleanTest3'); // has banana but not apple // Check that others are not included expect(entityNames).not.toContain('BooleanTest1'); // has both expect(entityNames).not.toContain('BooleanTest4'); // has neither }); });