[docs] Minor Docs fixes ( enhancements , restructure ) (#3748)

This commit is contained in:
Parth Sharma
2025-11-14 01:28:36 +05:30
committed by GitHub
parent 3297ec1a46
commit 2bca30ebe6
10 changed files with 507 additions and 506 deletions
+91 -5
View File
@@ -3,10 +3,96 @@ title: 'Add Memories'
openapi: post /v1/memories/
---
## Graph Memory
Add new facts, messages, or metadata to a user’s memory store. The Add Memories endpoint accepts either raw text or conversational turns and commits them asynchronously so the memory is ready for later search, retrieval, and graph queries.
To enable graph-based memory relationships, pass the `enable_graph=True` parameter. This creates relationships between entities in your memories for more contextual retrieval.
## Endpoint
<Note>
Learn more in the [Graph Memory documentation](/platform/features/graph-memory).
</Note>
- **Method**: `POST`
- **URL**: `/v1/memories/`
- **Content-Type**: `application/json`
Memories are processed asynchronously by default. The response contains queued events you can track while the platform finalizes enrichment.
## Required headers
| Header | Required | Description |
| --- | --- | --- |
| `Authorization: Bearer <MEM0_API_KEY>` | Yes | API key scoped to your workspace. |
| `Accept: application/json` | Yes | Ensures a JSON response. |
## Request body
Provide at least one message or direct memory string. Most callers supply `messages` so Mem0 can infer structured memories as part of ingestion.
<CodeGroup>
```json Basic request
{
"user_id": "alice",
"messages": [
{ "role": "user", "content": "I moved to Austin last month." }
],
"metadata": {
"source": "onboarding_form"
}
}
```
</CodeGroup>
### Common fields
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `user_id` | string | No* | Associates the memory with a user. Provide when you want the memory scoped to a specific identity. |
| `messages` | array | No* | Conversation turns for Mem0 to infer memories from. Each object should include `role` and `content`. |
| `memory` | string | No* | Direct memory text when you do not need inference. |
| `metadata` | object | Optional | Custom key/value metadata (e.g., `{"topic": "preferences"}`). |
| `infer` | boolean (default `true`) | Optional | Set to `false` to skip inference and store the provided text as-is. |
| `async_mode` | boolean (default `true`) | Optional | Controls asynchronous processing. Most clients leave this enabled. |
| `output_format` | string (default `v1.1`) | Optional | Response format. `v1.1` wraps results in a `results` array. |
> \* Provide either `messages` or `memory` to describe what you are storing. For scoped memories, include `user_id`. You can also attach `agent_id`, `app_id`, `run_id`, `project_id`, or `org_id` to refine ownership.
## Response
Successful requests return an array of events queued for processing. Each event includes the generated memory text and an identifier you can persist for auditing.
<CodeGroup>
```json 200 response
[
{
"id": "mem_01JF8ZS4Y0R0SPM13R5R6H32CJ",
"event": "ADD",
"data": {
"memory": "The user moved to Austin in 2025."
}
}
]
```
```json 400 response
{
"error": "400 Bad Request",
"details": {
"message": "Invalid input data. Please refer to the memory creation documentation at https://docs.mem0.ai/platform/quickstart#4-1-create-memories for correct formatting and required fields."
}
}
```
</CodeGroup>
## Graph relationships
Add Memories can enrich the knowledge graph on write. Set `enable_graph: true` to create entity nodes and relationships for the stored memory. Use this when you want downstream `get_all` or search calls to traverse connected entities.
<CodeGroup>
```json Graph-aware request
{
"user_id": "alice",
"messages": [
{ "role": "user", "content": "I met with Dr. Lee at General Hospital." }
],
"enable_graph": true
}
```
</CodeGroup>
The response follows the same format, and related entities become available in [Graph Memory](/platform/features/graph-memory) queries.
@@ -164,7 +164,7 @@ Ray can plan workouts that avoid aggravating Max's knee, without pulling in race
Run the basic loop for a week and check what's stored:
```python
memories = mem0_client.get_all(user_id="max")
memories = mem0_client.get_all(filters={"AND": [{"user_id": "max"}]})
print([m["memory"] for m in memories["results"]])
# Output: ["Max wants to run marathon under 4 hours", "hey", "lol ok", "cool thanks", "gtg bye"]
@@ -202,7 +202,7 @@ Now chat again:
chat("hey how's it going", user_id="max")
chat("I prefer trail running over roads", user_id="max")
memories = mem0_client.get_all(user_id="max")
memories = mem0_client.get_all(filters={"AND": [{"user_id": "max"}]})
print([m["memory"] for m in memories["results"]])
# Output: ["Max wants to run marathon under 4 hours", "Max prefers trail running over roads"]
@@ -411,7 +411,7 @@ Max changes his goal from sub-4 to sub-3:45:
```python
# Find the old memory
memories = mem0_client.get_all(user_id="max")
memories = mem0_client.get_all(filters={"AND": [{"user_id": "max"}]})
goal_memory = [m for m in memories["results"] if "sub-4" in m["memory"]][0]
# Update it
@@ -126,7 +126,7 @@ async def get_all_memory(
) -> str:
"""Retrieve all memories from Mem0"""
user_id = context.context.user_id or "default_user"
memories = await client.get_all(user_id=user_id)
memories = await client.get_all(filters={"AND": [{"user_id": user_id}]})
results = '\n'.join([result["memory"] for result in memories["results"]])
return str(results)
```
+6 -2
View File
@@ -75,14 +75,18 @@ await client.search("What is Alice's favorite sport?", { user_id: "alice" });
Retrieve all memories for a user asynchronously.
<Callout type="warning" title="Filters Required">
`get_all()` now requires filters to be specified.
</Callout>
<CodeGroup>
```python Python
await client.get_all(user_id="alice")
await client.get_all(filters={"AND": [{"user_id": "alice"}]})
```
```javascript JavaScript
await client.getAll({ user_id: "alice" });
await client.getAll({ filters: {"AND": [{"user_id": "alice"}]} });
```
</CodeGroup>
@@ -161,12 +161,14 @@ You can also retrieve all processed memories at any time:
```python Python
# Retrieve all memories for a user
memories = client.get_all(user_id="user-123")
# Note: get_all now requires filters
memories = client.get_all(filters={"AND": [{"user_id": "user-123"}]})
```
```javascript JavaScript
// Retrieve all memories for a user
const memories = await client.getAll({ user_id: "user-123" });
// Note: getAll now requires filters
const memories = await client.getAll({ filters: {"AND": [{"user_id": "user-123"}]} });
```
</CodeGroup>
@@ -302,7 +302,7 @@ messages = [
# Add the messages and check extracted memories
result = client.add(messages, user_id="test_user")
memories = client.get_all(user_id="test_user")
memories = client.get_all(filters={"AND": [{"user_id": "test_user"}]})
# Review if the right information was extracted
for memory in memories:
+5 -1
View File
@@ -67,10 +67,14 @@ client.search("What is Alice's favorite sport?", user_id="alice")
You can retrieve all memories using the `get_all` method.
<Callout type="warning" title="Filters Required">
`get_all()` now requires filters to be specified.
</Callout>
<CodeGroup>
```python Python
client.get_all(query="What is Alice's favorite sport?", user_id="alice")
client.get_all(filters={"AND": [{"user_id": "alice"}]})
```
```json Output
+6 -2
View File
@@ -187,12 +187,16 @@ console.log(results);
When retrieving all memories, Graph Memory provides additional relationship context:
<Callout type="warning" title="Filters Required">
`get_all()` now requires filters to be specified.
</Callout>
<CodeGroup>
```python Python
# Get all memories with graph context
memories = client.get_all(
user_id="joseph",
filters={"AND": [{"user_id": "joseph"}]},
enable_graph=True
)
@@ -202,7 +206,7 @@ print(memories)
```javascript JavaScript
// Get all memories with graph context
const memories = await client.getAll({
user_id: "joseph",
filters: {"AND": [{"user_id": "joseph"}]},
enable_graph: true
});
+389 -488
View File
@@ -1,515 +1,416 @@
---
title: Memory Filters v2
description: This guide covers the filtering system for retrieving and searching memories. You can filter by user sessions, agents, applications, content categories, and time ranges.
title: Memory Filters
description: Query and retrieve memories with powerful filtering capabilities. Filter by users, agents, content, time ranges, and more.
---
## Quick Start
> Memory filters provide a flexible way to query and retrieve specific memories from your memory store. You can filter by users, agents, content categories, time ranges, and combine multiple conditions using logical operators.
### Memories for a specific user
## When to use filters
```json
When working with large-scale memory stores, you need precise control over which memories to retrieve. Filters help you:
* **Isolate user data**: Retrieve memories for specific users while maintaining privacy
* **Debug and audit**: Export specific memory subsets for analysis
* **Target content**: Find memories with specific categories or metadata
* **Time-based queries**: Retrieve memories within specific date ranges
* **Performance optimization**: Reduce query complexity by pre-filtering
<Callout type="info" icon="info-circle" color="#7A5DFF">
Filters were introduced in v1.0.0 to provide precise control over memory retrieval.
</Callout>
## Filter structure
Filters use a nested JSON structure with logical operators at the root:
```python
# Basic structure
{
"AND": [
{ "user_id": "u1" }
]
"AND": [ # or "OR", "NOT"
{ "field": "value" },
{ "field": { "operator": "value" } }
]
}
```
### User memories across all runs
```json
{
"AND": [
{ "user_id": "u1" },
{ "run_id": "*" }
]
}
```
<Note>
Excludes null run_id values
</Note>
---
## Filter Structure
* Root must be **`AND`** or **`OR`** (or **`NOT`**) containing an **array** of conditions.
* A **condition** is either a simple equality `{ "user_id": "u1" }` or an operator clause `{ "created_at": { "gte": "..." } }`.
```json
{
"AND": [
{ "user_id": "u1" },
{ "run_id": "*" },
{ "created_at": { "lt": "2025-06-01T00:00:00Z" } },
{ "categories": { "in": ["finance", "health"] } }
]
}
```
**Accepted shapes**
```json
{ "AND": [ /* conditions... */ ] }
{ "OR": [ /* conditions... */ ] }
{ "NOT": [ /* conditions... */ ] }
```
---
## Available Fields
Use these to scope memories to primary entities:
| Field | Meaning |
| ---------- | ----------------------- |
| `user_id` | Filter by user/consumer |
| `agent_id` | Filter by AI agent |
| `app_id` | Filter by application |
| `run_id` | Filter by session/run |
---
## Wildcards
Wildcards (`"*"`) match **any non-null** value of that field. This means if a field is null, it won't be included in the results.
<Note>
Asterisks (`*`) exclude null values - only non-null fields will be matched
</Note>
```json
{ "AND": [ { "user_id": "*" } ] } // any record with a user_id
{ "AND": [ { "user_id": "*" }, { "run_id": "*" } ] } // require both non-null
{ "OR": [ { "user_id": "*" }, { "run_id": "*" } ] } // either non-null
```
---
## Operators and Fields
**Available Fields**
* **Entities**: `user_id`, `agent_id`, `app_id`, `run_id`
* **Time**: `created_at`, `updated_at`, `timestamp`
* **Content**: `categories`, `metadata`, `keywords`
* **Special**: `memory_ids` (array of IDs)
**Operators**
* `in`: Matches any of the values specified
* `gte`: Greater than or equal to
* `lte`: Less than or equal to
* `gt`: Greater than
* `lt`: Less than
* `ne`: Not equal to
* `contains`: Case-sensitive containment check
* `icontains`: Case-insensitive containment check
* `*`: Wildcard character that matches everything
**Field Structures**
```json
// Entity fields
{ "user_id": "u1" }
{ "agent_id": "a1" }
{ "app_id": "app1" }
{ "run_id": "run1" }
// Time fields
{ "created_at": { "gte": "2025-01-01T00:00:00Z" } }
{ "updated_at": { "lt": "2025-02-01T00:00:00Z" } }
// Categories (exact matching)
{ "categories": { "in": ["personal_information", "finance"] } }
// Categories (partial matching)
{ "categories": { "contains": "finance" } }
// Metadata (exact key-value match)
{ "metadata": { "key": "value" } }
// Keywords (text search)
{ "keywords": { "icontains": "budget" } }
// Memory IDs
{ "memory_ids": ["m1", "m2", "m3"] }
```
**Notes**
* `eq` is implied: `{ "user_id": "u1" }` ≡ `{ "user_id": { "eq": "u1" } }`
* `ne` includes **NULLs**: results where the field is either **not equal** or **missing**
* For `categories`, use `contains` for partial matching or `in` for exact matching
---
## Examples
### User and Agent Filters
**All memories for a specific user**
```json
{ "AND": [ { "user_id": "u1" } ] }
```
**All memories across all users (no agent/app/run)**
```json
{ "AND": [ { "user_id": "*" } ] }
```
<Note>
Excludes null user_id values
</Note>
**User memories across all runs**
```json
{ "AND": [ { "user_id": "u1" }, { "run_id": "*" } ] }
```
<Note>
Excludes null run_id values
</Note>
**All memories for a specific agent**
```json
{ "AND": [ { "agent_id": "a1" } ] }
```
**Agent memories across all runs**
```json
{ "AND": [ { "agent_id": "a1" }, { "run_id": "*" } ] }
```
<Note>
Excludes null run_id values
</Note>
### Content and Text Filters
**Search for text in user's memory content (case-insensitive)**
```json
{ "AND": [
{ "user_id": "u1" },
{ "keywords": { "icontains": "pizza" } }
] }
```
**Search for text in user's memory content (case-sensitive)**
```json
{ "AND": [
{ "user_id": "u1" },
{ "keywords": { "contains": "BudgetQ1" } }
] }
```
**User memories with specific categories**
```json
{ "AND": [
{ "user_id": "u1" },
{ "categories": { "in": ["finance", "health"] } }
] }
```
**User memories with specific metadata**
```json
{ "AND": [
{ "user_id": "u1" },
{ "metadata": { "foo": "bar" } }
] }
```
### Time-based Filters
**Memories created after a specific date**
```json
{ "AND": [
{ "user_id": "u1" },
{ "created_at": { "gt": "2025-01-01T00:00:00Z" } }
] }
```
**User memories within a date range**
```json
{ "AND": [
{ "user_id": "u1" },
{ "created_at": { "gte": "2025-01-01T00:00:00Z" } },
{ "created_at": { "lt": "2025-02-01T00:00:00Z" } }
] }
```
**Memories updated within a time window**
```json
{ "AND": [
{ "user_id": "u1" },
{ "updated_at": { "gte": "2025-05-01T00:00:00Z" } },
{ "updated_at": { "lte": "2025-05-31T23:59:59Z" } }
] }
```
### Advanced Filters
**Memories from multiple users**
```json
{ "AND": [ { "user_id": { "in": ["u1", "u2", "u3"] } } ] }
```
**Memories from either user or run**
```json
{ "OR": [ { "user_id": "u1" }, { "run_id": "run1" } ] }
```
**Memories that have both user and run (non-null)**
```json
{ "AND": [ { "user_id": "*" }, { "run_id": "*" } ] }
```
<Note>
Excludes null user_id and run_id values
</Note>
**User memories excluding specific categories**
```json
{ "AND": [
{ "user_id": "u1" },
{ "NOT": { "categories": { "in": ["spam", "test"] } } }
] }
```
**User memories by specific IDs**
```json
{ "AND": [
{ "user_id": "u1" },
{ "memory_ids": ["m1", "m2", "m3"] }
] }
```
**Complex filter: text + category + time**
```json
{ "AND": [
{ "user_id": "u1" },
{ "keywords": { "icontains": "invoice" } },
{ "categories": { "in": ["finance"] } },
{ "created_at": { "gte": "2025-03-01T00:00:00Z" } }
] }
```
### Comprehensive Filters
**All memories with non-null entities**
```json
{ "AND": [
{ "user_id": "*" },
{ "agent_id": "*" },
{ "run_id": "*" },
{ "app_id": "*" }
] }
```
<Note>
Excludes null values for all entity fields
</Note>
**All memories (including null entities)**
```json
{ "OR": [
{ "user_id": "*" },
{ "agent_id": "*" },
{ "run_id": "*" },
{ "app_id": "*" }
] }
```
---
## Common Patterns
**Single user memories**
```json
{ "AND": [ { "user_id": "u1" } ] }
```
**User memories across all runs**
```json
{ "AND": [ { "user_id": "u1" }, { "run_id": "*" } ] }
```
<Note>
Excludes null run_id values
</Note>
**All user memories (no agent/app/run)**
```json
{ "AND": [ { "user_id": "*" } ] }
```
<Note>
Excludes null user_id values
</Note>
**Agent with specific users**
```json
{ "AND": [ { "agent_id": "a1" }, { "user_id": { "in": ["u1", "u2"] } } ] }
```
**Search user's memory content (case-insensitive)**
```json
{ "AND": [
{ "user_id": "u1" },
{ "keywords": { "icontains": "budget" } }
] }
```
**Memories within date range**
```json
{ "AND": [
{ "user_id": "u1" },
{ "created_at": { "gte": "<from>" } },
{ "created_at": { "lt": "<to>" } }
] }
```
**Exclude specific categories**
```json
{ "AND": [
{ "user_id": "u1" },
{ "NOT": { "categories": { "in": ["spam", "test"] } } }
] }
```
**Get user's specific memories by ID**
```json
{ "AND": [
{ "user_id": "u1" },
{ "memory_ids": ["id1", "id2"] }
] }
```
---
## Available fields and operators
### Entity fields
| Field | Operators | Example |
|-------|-----------|---------|
| `user_id` | `=`, `!=`, `in`, `*` | `{"user_id": "user_123"}` |
| `agent_id` | `=`, `!=`, `in`, `*` | `{"agent_id": "*"}` |
| `app_id` | `=`, `!=`, `in`, `*` | `{"app_id": {"in": ["app1", "app2"]}}` |
| `run_id` | `=`, `!=`, `in`, `*` | `{"run_id": "*"}` |
### Time fields
| Field | Operators | Example |
|-------|-----------|---------|
| `created_at` | `>`, `>=`, `<`, `<=`, `=`, `!=` | `{"created_at": {"gte": "2024-01-01"}}` |
| `updated_at` | `>`, `>=`, `<`, `<=`, `=`, `!=` | `{"updated_at": {"lt": "2024-12-31"}}` |
| `timestamp` | `>`, `>=`, `<`, `<=`, `=`, `!=` | `{"timestamp": {"gt": "2024-01-01"}}` |
### Content fields
| Field | Operators | Example |
|-------|-----------|---------|
| `categories` | `=`, `!=`, `in`, `contains` | `{"categories": {"in": ["finance"]}}` |
| `metadata` | `=`, `!=` | `{"metadata": {"key": "value"}}` |
| `keywords` | `contains`, `icontains` | `{"keywords": {"icontains": "invoice"}}` |
### Special fields
| Field | Operators | Example |
|-------|-----------|---------|
| `memory_ids` | `in` | `{"memory_ids": ["id1", "id2"]}` |
<Callout type="warning" icon="exclamation-triangle" color="#F7B731">
The `*` wildcard matches any non-null value. Records with null values for that field are excluded.
</Callout>
## Common filter patterns
Use these ready-made filters to target typical retrieval scenarios without rebuilding logic from scratch.
<AccordionGroup>
<Accordion title="Single user">
```python
# Narrow to one user's memories
filters = {"AND": [{"user_id": "user_123"}]}
memories = client.get_all(filters=filters)
```
</Accordion>
<Accordion title="All users">
```python
# Wildcard skips null user_id entries
filters = {"AND": [{"user_id": "*"}]}
memories = client.get_all(filters=filters)
```
</Accordion>
<Accordion title="User across all runs">
```python
# Pair a user filter with a run wildcard
filters = {
"AND": [
{"user_id": "user_123"},
{"run_id": "*"}
]
}
memories = client.get_all(filters=filters)
```
</Accordion>
</AccordionGroup>
### Content search
Find memories containing specific text, categories, or metadata values.
<AccordionGroup>
<Accordion title="Text search">
```python
# Case-insensitive match
filters = {
"AND": [
{"user_id": "user_123"},
{"keywords": {"icontains": "pizza"}}
]
}
# Case-sensitive match
filters = {
"AND": [
{"user_id": "user_123"},
{"keywords": {"contains": "Invoice_2024"}}
]
}
```
</Accordion>
<Accordion title="Categories">
```python
# Match against category list
filters = {
"AND": [
{"user_id": "user_123"},
{"categories": {"in": ["finance", "health"]}}
]
}
# Partial category match
filters = {
"AND": [
{"user_id": "user_123"},
{"categories": {"contains": "finance"}}
]
}
```
</Accordion>
<Accordion title="Metadata">
```python
# Pin to a metadata attribute
filters = {
"AND": [
{"user_id": "user_123"},
{"metadata": {"source": "email"}}
]
}
```
</Accordion>
</AccordionGroup>
### Time-based filtering
Retrieve memories within specific date ranges using time operators.
<AccordionGroup>
<Accordion title="Date range">
```python
# Created in January 2024
filters = {
"AND": [
{"user_id": "user_123"},
{"created_at": {"gte": "2024-01-01T00:00:00Z"}},
{"created_at": {"lt": "2024-02-01T00:00:00Z"}}
]
}
# Updated recently
filters = {
"AND": [
{"user_id": "user_123"},
{"updated_at": {"gte": "2024-12-01T00:00:00Z"}}
]
}
```
</Accordion>
</AccordionGroup>
### Multiple criteria
Combine various filters for complex queries across different dimensions.
<AccordionGroup>
<Accordion title="Multiple users">
```python
# Expand scope to a short user list
filters = {
"AND": [
{"user_id": {"in": ["user_1", "user_2", "user_3"]}}
]
}
```
</Accordion>
<Accordion title="OR logic">
```python
# Return matches on either condition
filters = {
"OR": [
{"user_id": "user_123"},
{"run_id": "run_456"}
]
}
```
</Accordion>
<Accordion title="Exclude categories">
```python
# Wrap negative logic with NOT
filters = {
"AND": [
{"user_id": "user_123"},
{"NOT": {
"categories": {"in": ["spam", "test"]}
}}
]
}
```
</Accordion>
<Accordion title="Specific memory IDs">
```python
# Fetch a fixed set of memory IDs
filters = {
"AND": [
{"user_id": "user_123"},
{"memory_ids": ["mem_1", "mem_2", "mem_3"]}
]
}
```
</Accordion>
<Accordion title="All entities populated">
```python
# Require every entity field to be non-null
filters = {
"AND": [
{"user_id": "*"},
{"agent_id": "*"},
{"run_id": "*"},
{"app_id": "*"}
]
}
```
</Accordion>
</AccordionGroup>
## Advanced examples
Level up foundational patterns with compound filters that coordinate entity scope, tighten time windows, and weave in exclusion rules for high-precision retrievals.
<AccordionGroup>
<Accordion title="Multi-dimensional filtering">
```python
# Invoice memories in Q1 2024
filters = {
"AND": [
{"user_id": "user_123"},
{"keywords": {"icontains": "invoice"}},
{"categories": {"in": ["finance"]}},
{"created_at": {"gte": "2024-01-01T00:00:00Z"}},
{"created_at": {"lt": "2024-04-01T00:00:00Z"}}
]
}
```
</Accordion>
<Accordion title="Cross-entity relationships">
```python
# From specific agent, all users
filters = {
"AND": [
{"agent_id": "finance_bot"},
{"user_id": "*"}
]
}
# Any entity populated
filters = {
"OR": [
{"user_id": "*"},
{"agent_id": "*"},
{"run_id": "*"},
{"app_id": "*"}
]
}
```
</Accordion>
<Accordion title="Nested NOT/OR logic">
```python
# User memories from 2024, excluding spam and test
filters = {
"AND": [
{"user_id": "user_123"},
{"created_at": {"gte": "2024-01-01T00:00:00Z"}},
{"NOT": {
"OR": [
{"categories": {"in": ["spam"]}},
{"categories": {"in": ["test"]}}
]
}}
]
}
```
</Accordion>
</AccordionGroup>
## Best practices
<Callout type="tip" icon="lightbulb" color="#26A17B">
The root must be `AND`, `OR`, or `NOT` with an array of conditions.
</Callout>
<Callout type="tip" icon="lightbulb" color="#26A17B">
Use `"*"` to match any non-null value for a field.
</Callout>
<Callout type="warning" icon="exclamation-triangle" color="#E74C3C">
When you specify `user_id` only, other entity fields default to null. Use wildcards to include them.
</Callout>
## Troubleshooting
### "I filtered by `user_id`, but I don't see items that have an `agent_id`."
<AccordionGroup>
<Accordion title="Missing results with agent_id">
**Problem**: Filtered by `user_id` but don't see agent memories.
This is the **implicit null-scoping** rule. When you write only `{ "user_id": "u1" }`, the system also enforces `agent_id = NULL`, `run_id = NULL`, `app_id = NULL`. If you want any agent, add `{ "agent_id": "*" }`.
**Solution**: Add a wildcard for `agent_id` so non-null entries return:
```python
{"AND": [{"user_id": "user_123"}, {"agent_id": "*"}]}
```
</Accordion>
```json
{ "AND": [ { "user_id": "u1" }, { "agent_id": "*" } ] }
```
<Accordion title="ne operator returns too much">
**Problem**: `ne` comparison pulls in records with null values.
### "My `ne` seems to return more than I expect."
**Solution**: Pair `ne` with a wildcard guard:
```python
{"AND": [{"agent_id": "*"}, {"agent_id": {"ne": "old_agent"}}]}
```
</Accordion>
`ne` returns rows where the field is **not equal OR NULL**. If you need "not equal and **definitely present**", combine with a wildcard.
<Accordion title="Case-insensitive search">
**Solution**: Swap to `icontains` to normalize casing.
</Accordion>
```json
{ "AND": [ { "agent_id": "*" }, { "agent_id": { "ne": "a1" } } ] }
```
<Accordion title="Date range between two dates">
**Solution**: Use `gte` for the start and `lt` for the end boundary:
```python
{"AND": [
{"created_at": {"gte": "2024-01-01"}},
{"created_at": {"lt": "2024-02-01"}}
]}
```
</Accordion>
### "Case-insensitive search?"
Use `icontains`.
```json
{ "AND": [ { "keywords": { "icontains": "receipt" } } ] }
```
### "Between two dates?"
Use `gte` and `lt` (or `lte`) together.
```json
{ "AND": [
{ "user_id": "u1" },
{ "created_at": { "gte": "2025-01-01T00:00:00Z" } },
{ "created_at": { "lt": "2025-02-01T00:00:00Z" } }
] }
```
### "Complex logic with NOT"
`NOT` can wrap a single condition or an array. Example: user `u1` but not category `spam` or `test`.
```json
{ "AND": [
{ "user_id": "u1" },
{ "NOT": { "categories": { "in": ["spam", "test"] } } }
] }
```
### "Metadata matching isn't working."
Ensure you match the **exact JSON shape** at the top level.
```json
{ "AND": [ { "metadata": { "foo": "bar" } } ] }
```
### "I want all users, all agents, all runs."
Be explicit with wildcards for **each** entity dimension.
```json
{ "AND": [ { "user_id": "*" }, { "agent_id": "*" }, { "run_id": "*" } ] }
```
---
<Accordion title="Metadata filter not working">
**Solution**: Match top-level metadata keys exactly:
```python
{"metadata": {"source": "email"}}
```
</Accordion>
</AccordionGroup>
## FAQ
**Q: Do I have to wrap my filter in `AND` or `OR`?**
<AccordionGroup>
<Accordion title="Do I need AND/OR/NOT?">
Yes. The root must be a logical operator with an array.
</Accordion>
Yes. The root must be one of `AND`, `OR`, or `NOT`.
<Accordion title="What does * match?">
Any non-null value. Nulls are excluded.
</Accordion>
**Q: What does the wildcard `"*"` match?**
<Accordion title="Why use wildcards?">
Unspecified fields default to NULL. Use `"*"` to include non-null values.
</Accordion>
Any **non-null** value for that field.
<Accordion title="Is = required?">
No. Equality is the default: `{"user_id": "u1"}` works.
</Accordion>
**Q: Why are results "missing" unless I add wildcards?**
<Accordion title="Can I filter nested metadata?">
Only top-level keys are supported.
</Accordion>
Because unspecified entity fields default to **`NULL`** due to restrictive scoping.
<Accordion title="How to search text?">
Use `keywords` with `contains` (case-sensitive) or `icontains` (case-insensitive).
</Accordion>
**Q: Is `eq` required?**
No—equality is the default. `{ "user_id": "u1" }` is enough.
**Q: Does `ne` include NULLs?**
Yes. Use `{ "field": "*" }` together with `ne` if you need "present and not equal".
**Q: How do I search the memory text?**
Use `keywords` with `contains` or `icontains`.
**Q: Can I filter nested metadata keys?**
Currently target **top-level** keys as shown: `{ "metadata": { "foo": "bar" } }`.
<Accordion title="Can I nest AND/OR?">
```python
{
"AND": [
{"user_id": "user_123"},
{"OR": [
{"categories": "finance"},
{"categories": "health"}
]}
]
}
```
</Accordion>
</AccordionGroup>
+1 -1
View File
@@ -119,7 +119,7 @@ Walk through a real request/response. Include sample payloads and highlight nota
## Best practices
- Keep criteria minimal—overfiltering hurts recall.
- Pair with Memory Filters v2 for hybrid scoring.
- Pair with Memory Filters for hybrid scoring.
{/* DEBUG: verify CTA targets */}