# Filter Content by Entities

## User Intent

"How do I find all content mentioning a specific person or organization? Show me entity-based content filtering."

## Operation

**SDK Method**: `queryContents()` with `observations` filter\
**GraphQL Query**: `queryContents`\
**Use Case**: Entity-driven content discovery

## Prerequisites

* Content with extracted entities
* Knowledge of entity IDs or names
* Understanding of Observable model

***

## Complete Code Example (TypeScript)

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

const graphlit = new Graphlit();

// Example 1: Find all content mentioning a person
async function findContentByPerson(personName: string) {
  // Step 1: Find the person entity
  const people = await graphlit.queryObservables({
    search: personName,
    filter: { types: [ObservableTypes.Person] }
  });
  
  if (people.observables.results.length === 0) {
    console.log(`No entity found for: ${personName}`);
    return;
  }
  
  const person = people.observables.results[0];
  console.log(`Found entity: ${person.observable.name} (${person.observable.id})\n`);
  
  // Step 2: Find all content mentioning this person
  const content = await graphlit.queryContents({
    
      observations: [{
        type: ObservableTypes.Person,
        observable: { id: person.observable.id }
      }]
    });
  
  console.log(`Content mentioning ${person.observable.name}: ${content.contents.results.length}`);
  
  // Group by type
  const byType = new Map<string, number>();
  content.contents.results.forEach(item => {
    const type = item.type || 'UNKNOWN';
    byType.set(type, (byType.get(type) || 0) + 1);
  });
  
  console.log('\nBy content type:');
  byType.forEach((count, type) => {
    console.log(`  ${type}: ${count}`);
  });
  
  return content.contents.results;
}

// Example 2: Find content mentioning multiple entities (AND logic)
async function findContentWithMultipleEntities(
  personName: string,
  orgName: string
) {
  // Find entities
  const person = await graphlit.queryObservables({
    search: personName,
    filter: { types: [ObservableTypes.Person] }
  });
  
  const org = await graphlit.queryObservables({
    search: orgName,
    filter: { types: [ObservableTypes.Organization] }
  });
  
  if (person.observables.results.length === 0 || org.observables.results.length === 0) {
    console.log('One or both entities not found');
    return;
  }
  
  // Find content mentioning BOTH
  const content = await graphlit.queryContents({
    
      observations: [
        {
          type: ObservableTypes.Person,
          observable: { id: person.observables.results[0].observable.id }
        },
        {
          type: ObservableTypes.Organization,
          observable: { id: org.observables.results[0].observable.id }
        }
      ]
    });
  
  console.log(`Content mentioning both ${personName} and ${orgName}: ${content.contents.results.length}`);
  
  return content.contents.results;
}

// Run examples
await findContentByPerson("Kirk Marple");
console.log('\n---\n');
await findContentWithMultipleEntities("Kirk Marple", "Graphlit");
```

***

## Key Patterns

### Pattern 1: Single Entity Filter

Find all content mentioning one entity:

```typescript
const content = await graphlit.queryContents({
  
    observations: [{
      type: ObservableTypes.Person,
      observable: { id: entityId }
    }]
  });
```

### Pattern 2: Multiple Entities (AND)

Content mentioning ALL specified entities:

```typescript
const content = await graphlit.queryContents({
  
    observations: [
      { observable: { id: entityId1 } },
      { observable: { id: entityId2 } }
    ]
  });
```

### Pattern 3: Entity Type Filter

All content with any entity of type:

```typescript
const content = await graphlit.queryContents({
  
    observations: [{
      type: ObservableTypes.Organization
      // No specific observable ID = any organization
    }]
  });
```

### Pattern 4: Combined Filters

Entity + content type + date:

```typescript
const content = await graphlit.queryContents({
  
    types: [ContentTypes.Email],  // Only emails
    observations: [{
      type: ObservableTypes.Person,
      observable: { id: personId }
    }],
    creationDateRange: {
      from: '2024-01-01'
    }
  });
```

***

## Use Cases

**1. Entity Timeline**: Track mentions over time\
**2. Cross-Source Discovery**: Find entity across email, Slack, docs\
**3. Relationship Mapping**: Content connecting two entities\
**4. Entity-Specific Search**: Scope search to entity context\
**5. Content Audit**: What references this person/org?

***

## Developer Hints

* Entity filters query graph database (slower than pure content queries)
* Combine with content type filters for speed
* Use entity search first to get IDs
* Multiple entity filters = AND logic (all must match)
* Great for focused discovery

***


---

# 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/content-filter-by-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.
