# 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

***
