# Query Entities

## Observable: Query Entities

### User Intent

"I want to query extracted entities (people, organizations, topics) from my knowledge graph"

### Operation

* **SDK Method**: `graphlit.queryObservables()`
* **GraphQL**: `queryObservables` query
* **Entity Type**: Observable
* **Common Use Cases**: Knowledge graph queries, entity search, relationship discovery, semantic network exploration

### TypeScript (Canonical)

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

const graphlit = new Graphlit();

// Query all people and organizations
const observablesResponse = await graphlit.queryObservables({
  observableTypes: [
    ObservableTypes.Person,
    ObservableTypes.Organization
  ]
});

console.log(`Found ${observablesResponse.observables.results.length} entities`);

observablesResponse.observables.results.forEach(entity => {
  console.log(`${entity.type}: ${entity.name}`);
  if (entity.description) {
    console.log(`  Description: ${entity.description}`);
  }
});

// Search for specific entity
const searchResponse = await graphlit.queryObservables({
  observableTypes: [ObservableTypes.Person],
  search: 'John Smith'
});

// Query entities from specific content
const contentEntities = await graphlit.queryObservables({
  contents: [{ id: contentId }]
});

console.log(`Entities in content: ${contentEntities.observables.results.length}`);
```

## Query entities (snake\_case)

response = await graphlit.queryObservables( filter=ObservableFilterInput( observable\_types=\[ ObservableTypes.PERSON, ObservableTypes.ORGANIZATION ] ) )

for entity in response.observables.results: print(f"{entity.type}: {entity.name}")

## Search for specific entity

search\_response = await graphlit.queryObservables( filter=ObservableFilterInput( observable\_types=\[ObservableTypes.PERSON], search="John Smith" ) )

````

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

var client = new Graphlit();

// Query entities (PascalCase)
var response = await graphlit.QueryObservables(new ObservableFilter {
    ObservableTypes = new[] {
        ObservableTypes.Person,
        ObservableTypes.Organization
    }
});

foreach (var entity in response.Observables.Results)
{
    Console.WriteLine($"{entity.Type}: {entity.Name}");
}

// Search for specific entity
var searchResponse = await graphlit.QueryObservables(new ObservableFilter {
    ObservableTypes = new[] { ObservableTypes.Person },
    Search = "John Smith"
});
````

### Parameters

#### ObservableFilter (Optional)

* **`observableTypes`** (ObservableTypes\[]): Types to query
  * `PERSON` - People, individuals
  * `ORGANIZATION` - Companies, institutions
  * `PLACE` - Locations, addresses
  * `PRODUCT` - Products, services
  * `EVENT` - Events, occurrences
  * `TOPIC` - Concepts, themes
  * Custom types (if defined in extraction workflow)
* **`search`** (string): Search query for entity names
* **`contents`** (EntityReferenceFilter\[]): Filter by source content
* **`limit`** (int): Max results (default: 100)
* **`offset`** (int): Pagination offset

### Response

```typescript
{
  observables: {
    results: Observable[];  // Array of entities
  }
}

interface Observable {
  id: string;               // Entity ID
  name: string;             // Entity name
  type: ObservableType;     // Entity type
  description?: string;     // Entity description
  uri?: string;             // Related URI
  occurrenceCount: number;  // Times mentioned
  contents?: Content[];     // Source content
}
```

### Developer Hints

#### Entities Must Be Extracted First

**Important**: You must use an extraction workflow during content ingestion to create entities.

```typescript
// 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 workflow
await graphlit.ingestUri(
  uri, undefined, undefined, undefined, true,
  { id: workflow.createWorkflow.id }
);

// 3. Now query entities
const entities = await graphlit.queryObservables();
```

#### Filter by Entity Type

```typescript
// Query specific types only
const people = await graphlit.queryObservables({
  observableTypes: [ObservableTypes.Person]
});

const orgs = await graphlit.queryObservables({
  observableTypes: [ObservableTypes.Organization]
});

// Multiple types
const peopleAndOrgs = await graphlit.queryObservables({
  observableTypes: [
    ObservableTypes.Person,
    ObservableTypes.Organization
  ]
});
```

#### Search for Entities

```typescript
// Search by name
const results = await graphlit.queryObservables({
  search: 'Microsoft',
  observableTypes: [ObservableTypes.Organization]
});

// Fuzzy matching works
const fuzzy = await graphlit.queryObservables({
  search: 'micro',  // Finds "Microsoft", "Microservices", etc.
});
```

#### Entity Occurrence Count

```typescript
// Get most frequently mentioned entities
const entities = await graphlit.queryObservables({
  observableTypes: [ObservableTypes.Person],
  limit: 10
});

// Sorted by occurrence count (most mentioned first)
entities.observables.results.forEach(entity => {
  console.log(`${entity.name}: mentioned ${entity.occurrenceCount} times`);
});
```

### Variations

#### 1. Query All Entities

Get all extracted entities:

```typescript
const allEntities = await graphlit.queryObservables();

console.log(`Total entities: ${allEntities.observables.results.length}`);
```

#### 2. Query People Only

Find all people:

```typescript
const people = await graphlit.queryObservables({
  observableTypes: [ObservableTypes.Person]
});

people.observables.results.forEach(person => {
  console.log(person.name);
});
```

#### 3. Search for Specific Entity

Find specific entity by name:

```typescript
const microsoft = await graphlit.queryObservables({
  search: 'Microsoft',
  observableTypes: [ObservableTypes.Organization]
});

if (microsoft.observables.results.length > 0) {
  const entity = microsoft.observables.results[0];
  console.log(`Found: ${entity.name}`);
  console.log(`Mentioned: ${entity.occurrenceCount} times`);
}
```

#### 4. Query Entities from Specific Content

Get entities from specific document:

```typescript
const contentEntities = await graphlit.queryObservables({
  contents: [{ id: contentId }]
});

console.log('Entities in document:');
contentEntities.observables.results.forEach(entity => {
  console.log(`- ${entity.type}: ${entity.name}`);
});
```

#### 5. Top Mentioned Entities

Get most frequently mentioned:

```typescript
const topEntities = await graphlit.queryObservables({
  observableTypes: [
    ObservableTypes.Person,
    ObservableTypes.Organization
  ],
  limit: 20  // Top 20
});

console.log('Top mentioned entities:');
topEntities.observables.results.forEach((entity, index) => {
  console.log(`${index + 1}. ${entity.name} (${entity.occurrenceCount} mentions)`);
});
```

#### 6. Custom Entity Types

Query custom extraction types:

```typescript
// If you extracted custom types like "Contract", "Regulation"
const contracts = await graphlit.queryObservables({
  observableTypes: ['Contract']  // Custom type
});

contracts.observables.results.forEach(contract => {
  console.log(`Contract: ${contract.name}`);
});
```

### Common Issues

**Issue**: No entities returned\
**Solution**: Ensure content was ingested with extraction workflow. Check workflow has entity extraction configured.

**Issue**: Wrong entity types extracted\
**Solution**: Specify `observableTypes` in extraction workflow. Use `customTypes` for domain-specific entities.

**Issue**: Entity names are incomplete\
**Solution**: Use better extraction model (Claude Sonnet 3.7, GPT-4o). Check source content quality.

**Issue**: Too many irrelevant entities\
**Solution**: Filter by `observableTypes`. Use `search` parameter to narrow results.

**Issue**: Entity occurrence count seems wrong\
**Solution**: Count reflects mentions across all content. Entity may be mentioned multiple times per document.

### Production Example

**Entity discovery pipeline**:

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

// 2. Ingest content with extraction
await graphlit.ingestUri(
  'https://company-docs.com/page.html',
  undefined, undefined, undefined, true,
  { id: workflow.createWorkflow.id }
);

// 3. Query extracted entities
const entities = await graphlit.queryObservables({
  observableTypes: [
    ObservableTypes.Person,
    ObservableTypes.Organization,
    ObservableTypes.Product
  ]
});

// 4. Display results
console.log(`\nExtracted ${entities.observables.results.length} entities:`);
entities.observables.results.forEach(entity => {
  console.log(`\n${entity.type}: ${entity.name}`);
  console.log(`  Mentions: ${entity.occurrenceCount}`);
  if (entity.description) {
    console.log(`  Description: ${entity.description}`);
  }
});
```

**Entity search interface**:

```typescript
// Search for entities by user query
async function searchEntities(query: string, types?: ObservableTypes[]) {
  const results = await graphlit.queryObservables({
    search: query,
    observableTypes: types,
    limit: 50
  });
  
  return results.observables.results.map(entity => ({
    id: entity.id,
    name: entity.name,
    type: entity.type,
    mentions: entity.occurrenceCount,
    description: entity.description
  }));
}

// Usage
const people = await searchEntities('John', [ObservableTypes.Person]);
const companies = await searchEntities('Tech', [ObservableTypes.Organization]);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.graphlit.dev/api-guides/use-cases/knowledge-graph/observable-query-entities.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
