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

This commit is contained in:
Parth Sharma
2025-11-13 11:58:36 -08:00
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/ 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> - **Method**: `POST`
Learn more in the [Graph Memory documentation](/platform/features/graph-memory). - **URL**: `/v1/memories/`
</Note> - **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: Run the basic loop for a week and check what's stored:
```python ```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"]]) print([m["memory"] for m in memories["results"]])
# Output: ["Max wants to run marathon under 4 hours", "hey", "lol ok", "cool thanks", "gtg bye"] # 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("hey how's it going", user_id="max")
chat("I prefer trail running over roads", 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"]]) print([m["memory"] for m in memories["results"]])
# Output: ["Max wants to run marathon under 4 hours", "Max prefers trail running over roads"] # 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 ```python
# Find the old memory # 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] goal_memory = [m for m in memories["results"] if "sub-4" in m["memory"]][0]
# Update it # Update it
@@ -126,7 +126,7 @@ async def get_all_memory(
) -> str: ) -> str:
"""Retrieve all memories from Mem0""" """Retrieve all memories from Mem0"""
user_id = context.context.user_id or "default_user" 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"]]) results = '\n'.join([result["memory"] for result in memories["results"]])
return str(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. Retrieve all memories for a user asynchronously.
<Callout type="warning" title="Filters Required">
`get_all()` now requires filters to be specified.
</Callout>
<CodeGroup> <CodeGroup>
```python Python ```python Python
await client.get_all(user_id="alice") await client.get_all(filters={"AND": [{"user_id": "alice"}]})
``` ```
```javascript JavaScript ```javascript JavaScript
await client.getAll({ user_id: "alice" }); await client.getAll({ filters: {"AND": [{"user_id": "alice"}]} });
``` ```
</CodeGroup> </CodeGroup>
@@ -161,12 +161,14 @@ You can also retrieve all processed memories at any time:
```python Python ```python Python
# Retrieve all memories for a user # 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 ```javascript JavaScript
// Retrieve all memories for a user // 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> </CodeGroup>
@@ -302,7 +302,7 @@ messages = [
# Add the messages and check extracted memories # Add the messages and check extracted memories
result = client.add(messages, user_id="test_user") 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 # Review if the right information was extracted
for memory in memories: 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. 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> <CodeGroup>
```python Python ```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 ```json Output
+6 -2
View File
@@ -187,12 +187,16 @@ console.log(results);
When retrieving all memories, Graph Memory provides additional relationship context: 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> <CodeGroup>
```python Python ```python Python
# Get all memories with graph context # Get all memories with graph context
memories = client.get_all( memories = client.get_all(
user_id="joseph", filters={"AND": [{"user_id": "joseph"}]},
enable_graph=True enable_graph=True
) )
@@ -202,7 +206,7 @@ print(memories)
```javascript JavaScript ```javascript JavaScript
// Get all memories with graph context // Get all memories with graph context
const memories = await client.getAll({ const memories = await client.getAll({
user_id: "joseph", filters: {"AND": [{"user_id": "joseph"}]},
enable_graph: true enable_graph: true
}); });
+389 -488
View File
@@ -1,515 +1,416 @@
--- ---
title: Memory Filters v2 title: Memory Filters
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. 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": [ "AND": [ # or "OR", "NOT"
{ "user_id": "u1" } { "field": "value" },
] { "field": { "operator": "value" } }
]
} }
``` ```
### User memories across all runs ## Available fields and operators
```json ### Entity fields
{ | Field | Operators | Example |
"AND": [ |-------|-----------|---------|
{ "user_id": "u1" }, | `user_id` | `=`, `!=`, `in`, `*` | `{"user_id": "user_123"}` |
{ "run_id": "*" } | `agent_id` | `=`, `!=`, `in`, `*` | `{"agent_id": "*"}` |
] | `app_id` | `=`, `!=`, `in`, `*` | `{"app_id": {"in": ["app1", "app2"]}}` |
} | `run_id` | `=`, `!=`, `in`, `*` | `{"run_id": "*"}` |
```
### Time fields
<Note> | Field | Operators | Example |
Excludes null run_id values |-------|-----------|---------|
</Note> | `created_at` | `>`, `>=`, `<`, `<=`, `=`, `!=` | `{"created_at": {"gte": "2024-01-01"}}` |
| `updated_at` | `>`, `>=`, `<`, `<=`, `=`, `!=` | `{"updated_at": {"lt": "2024-12-31"}}` |
| `timestamp` | `>`, `>=`, `<`, `<=`, `=`, `!=` | `{"timestamp": {"gt": "2024-01-01"}}` |
---
### Content fields
## Filter Structure | Field | Operators | Example |
|-------|-----------|---------|
* Root must be **`AND`** or **`OR`** (or **`NOT`**) containing an **array** of conditions. | `categories` | `=`, `!=`, `in`, `contains` | `{"categories": {"in": ["finance"]}}` |
* A **condition** is either a simple equality `{ "user_id": "u1" }` or an operator clause `{ "created_at": { "gte": "..." } }`. | `metadata` | `=`, `!=` | `{"metadata": {"key": "value"}}` |
| `keywords` | `contains`, `icontains` | `{"keywords": {"icontains": "invoice"}}` |
```json
{ ### Special fields
"AND": [ | Field | Operators | Example |
{ "user_id": "u1" }, |-------|-----------|---------|
{ "run_id": "*" }, | `memory_ids` | `in` | `{"memory_ids": ["id1", "id2"]}` |
{ "created_at": { "lt": "2025-06-01T00:00:00Z" } },
{ "categories": { "in": ["finance", "health"] } } <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
**Accepted shapes**
Use these ready-made filters to target typical retrieval scenarios without rebuilding logic from scratch.
```json
{ "AND": [ /* conditions... */ ] } <AccordionGroup>
{ "OR": [ /* conditions... */ ] } <Accordion title="Single user">
{ "NOT": [ /* conditions... */ ] } ```python
``` # Narrow to one user's memories
filters = {"AND": [{"user_id": "user_123"}]}
--- memories = client.get_all(filters=filters)
```
## Available Fields </Accordion>
Use these to scope memories to primary entities: <Accordion title="All users">
```python
| Field | Meaning | # Wildcard skips null user_id entries
| ---------- | ----------------------- | filters = {"AND": [{"user_id": "*"}]}
| `user_id` | Filter by user/consumer | memories = client.get_all(filters=filters)
| `agent_id` | Filter by AI agent | ```
| `app_id` | Filter by application | </Accordion>
| `run_id` | Filter by session/run |
<Accordion title="User across all runs">
--- ```python
# Pair a user filter with a run wildcard
## Wildcards filters = {
"AND": [
Wildcards (`"*"`) match **any non-null** value of that field. This means if a field is null, it won't be included in the results. {"user_id": "user_123"},
{"run_id": "*"}
<Note> ]
Asterisks (`*`) exclude null values - only non-null fields will be matched }
</Note> memories = client.get_all(filters=filters)
```
```json </Accordion>
{ "AND": [ { "user_id": "*" } ] } // any record with a user_id </AccordionGroup>
{ "AND": [ { "user_id": "*" }, { "run_id": "*" } ] } // require both non-null
{ "OR": [ { "user_id": "*" }, { "run_id": "*" } ] } // either non-null ### Content search
```
Find memories containing specific text, categories, or metadata values.
---
<AccordionGroup>
## Operators and Fields <Accordion title="Text search">
```python
**Available Fields** # Case-insensitive match
filters = {
* **Entities**: `user_id`, `agent_id`, `app_id`, `run_id` "AND": [
* **Time**: `created_at`, `updated_at`, `timestamp` {"user_id": "user_123"},
* **Content**: `categories`, `metadata`, `keywords` {"keywords": {"icontains": "pizza"}}
* **Special**: `memory_ids` (array of IDs) ]
}
**Operators**
# Case-sensitive match
* `in`: Matches any of the values specified filters = {
* `gte`: Greater than or equal to "AND": [
* `lte`: Less than or equal to {"user_id": "user_123"},
* `gt`: Greater than {"keywords": {"contains": "Invoice_2024"}}
* `lt`: Less than ]
* `ne`: Not equal to }
* `contains`: Case-sensitive containment check ```
* `icontains`: Case-insensitive containment check </Accordion>
* `*`: Wildcard character that matches everything
<Accordion title="Categories">
**Field Structures** ```python
# Match against category list
```json filters = {
// Entity fields "AND": [
{ "user_id": "u1" } {"user_id": "user_123"},
{ "agent_id": "a1" } {"categories": {"in": ["finance", "health"]}}
{ "app_id": "app1" } ]
{ "run_id": "run1" } }
// Time fields # Partial category match
{ "created_at": { "gte": "2025-01-01T00:00:00Z" } } filters = {
{ "updated_at": { "lt": "2025-02-01T00:00:00Z" } } "AND": [
{"user_id": "user_123"},
// Categories (exact matching) {"categories": {"contains": "finance"}}
{ "categories": { "in": ["personal_information", "finance"] } } ]
// Categories (partial matching) }
{ "categories": { "contains": "finance" } } ```
</Accordion>
// Metadata (exact key-value match)
{ "metadata": { "key": "value" } } <Accordion title="Metadata">
```python
// Keywords (text search) # Pin to a metadata attribute
{ "keywords": { "icontains": "budget" } } filters = {
"AND": [
// Memory IDs {"user_id": "user_123"},
{ "memory_ids": ["m1", "m2", "m3"] } {"metadata": {"source": "email"}}
``` ]
}
**Notes** ```
</Accordion>
* `eq` is implied: `{ "user_id": "u1" }` ≡ `{ "user_id": { "eq": "u1" } }` </AccordionGroup>
* `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 ### Time-based filtering
--- Retrieve memories within specific date ranges using time operators.
## Examples <AccordionGroup>
<Accordion title="Date range">
### User and Agent Filters ```python
# Created in January 2024
**All memories for a specific user** filters = {
"AND": [
```json {"user_id": "user_123"},
{ "AND": [ { "user_id": "u1" } ] } {"created_at": {"gte": "2024-01-01T00:00:00Z"}},
``` {"created_at": {"lt": "2024-02-01T00:00:00Z"}}
]
**All memories across all users (no agent/app/run)** }
```json # Updated recently
{ "AND": [ { "user_id": "*" } ] } filters = {
``` "AND": [
{"user_id": "user_123"},
<Note> {"updated_at": {"gte": "2024-12-01T00:00:00Z"}}
Excludes null user_id values ]
</Note> }
```
**User memories across all runs** </Accordion>
</AccordionGroup>
```json
{ "AND": [ { "user_id": "u1" }, { "run_id": "*" } ] } ### Multiple criteria
```
Combine various filters for complex queries across different dimensions.
<Note>
Excludes null run_id values <AccordionGroup>
</Note> <Accordion title="Multiple users">
```python
**All memories for a specific agent** # Expand scope to a short user list
filters = {
```json "AND": [
{ "AND": [ { "agent_id": "a1" } ] } {"user_id": {"in": ["user_1", "user_2", "user_3"]}}
``` ]
}
**Agent memories across all runs** ```
</Accordion>
```json
{ "AND": [ { "agent_id": "a1" }, { "run_id": "*" } ] } <Accordion title="OR logic">
``` ```python
# Return matches on either condition
<Note> filters = {
Excludes null run_id values "OR": [
</Note> {"user_id": "user_123"},
{"run_id": "run_456"}
### Content and Text Filters ]
}
**Search for text in user's memory content (case-insensitive)** ```
</Accordion>
```json
{ "AND": [ <Accordion title="Exclude categories">
{ "user_id": "u1" }, ```python
{ "keywords": { "icontains": "pizza" } } # Wrap negative logic with NOT
] } filters = {
``` "AND": [
{"user_id": "user_123"},
**Search for text in user's memory content (case-sensitive)** {"NOT": {
"categories": {"in": ["spam", "test"]}
```json }}
{ "AND": [ ]
{ "user_id": "u1" }, }
{ "keywords": { "contains": "BudgetQ1" } } ```
] } </Accordion>
```
<Accordion title="Specific memory IDs">
**User memories with specific categories** ```python
# Fetch a fixed set of memory IDs
```json filters = {
{ "AND": [ "AND": [
{ "user_id": "u1" }, {"user_id": "user_123"},
{ "categories": { "in": ["finance", "health"] } } {"memory_ids": ["mem_1", "mem_2", "mem_3"]}
] } ]
``` }
```
**User memories with specific metadata** </Accordion>
```json <Accordion title="All entities populated">
{ "AND": [ ```python
{ "user_id": "u1" }, # Require every entity field to be non-null
{ "metadata": { "foo": "bar" } } filters = {
] } "AND": [
``` {"user_id": "*"},
{"agent_id": "*"},
### Time-based Filters {"run_id": "*"},
{"app_id": "*"}
**Memories created after a specific date** ]
}
```json ```
{ "AND": [ </Accordion>
{ "user_id": "u1" }, </AccordionGroup>
{ "created_at": { "gt": "2025-01-01T00:00:00Z" } }
] } ## 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.
**User memories within a date range**
<AccordionGroup>
```json <Accordion title="Multi-dimensional filtering">
{ "AND": [ ```python
{ "user_id": "u1" }, # Invoice memories in Q1 2024
{ "created_at": { "gte": "2025-01-01T00:00:00Z" } }, filters = {
{ "created_at": { "lt": "2025-02-01T00:00:00Z" } } "AND": [
] } {"user_id": "user_123"},
``` {"keywords": {"icontains": "invoice"}},
{"categories": {"in": ["finance"]}},
**Memories updated within a time window** {"created_at": {"gte": "2024-01-01T00:00:00Z"}},
{"created_at": {"lt": "2024-04-01T00:00:00Z"}}
```json ]
{ "AND": [ }
{ "user_id": "u1" }, ```
{ "updated_at": { "gte": "2025-05-01T00:00:00Z" } }, </Accordion>
{ "updated_at": { "lte": "2025-05-31T23:59:59Z" } }
] } <Accordion title="Cross-entity relationships">
``` ```python
# From specific agent, all users
### Advanced Filters filters = {
"AND": [
**Memories from multiple users** {"agent_id": "finance_bot"},
{"user_id": "*"}
```json ]
{ "AND": [ { "user_id": { "in": ["u1", "u2", "u3"] } } ] } }
```
# Any entity populated
filters = {
**Memories from either user or run** "OR": [
{"user_id": "*"},
```json {"agent_id": "*"},
{ "OR": [ { "user_id": "u1" }, { "run_id": "run1" } ] } {"run_id": "*"},
``` {"app_id": "*"}
]
**Memories that have both user and run (non-null)** }
```
```json </Accordion>
{ "AND": [ { "user_id": "*" }, { "run_id": "*" } ] }
``` <Accordion title="Nested NOT/OR logic">
```python
<Note> # User memories from 2024, excluding spam and test
Excludes null user_id and run_id values filters = {
</Note> "AND": [
{"user_id": "user_123"},
**User memories excluding specific categories** {"created_at": {"gte": "2024-01-01T00:00:00Z"}},
{"NOT": {
```json "OR": [
{ "AND": [ {"categories": {"in": ["spam"]}},
{ "user_id": "u1" }, {"categories": {"in": ["test"]}}
{ "NOT": { "categories": { "in": ["spam", "test"] } } } ]
] } }}
``` ]
}
**User memories by specific IDs** ```
</Accordion>
```json </AccordionGroup>
{ "AND": [
{ "user_id": "u1" }, ## Best practices
{ "memory_ids": ["m1", "m2", "m3"] }
] } <Callout type="tip" icon="lightbulb" color="#26A17B">
``` The root must be `AND`, `OR`, or `NOT` with an array of conditions.
</Callout>
**Complex filter: text + category + time**
<Callout type="tip" icon="lightbulb" color="#26A17B">
```json Use `"*"` to match any non-null value for a field.
{ "AND": [ </Callout>
{ "user_id": "u1" },
{ "keywords": { "icontains": "invoice" } }, <Callout type="warning" icon="exclamation-triangle" color="#E74C3C">
{ "categories": { "in": ["finance"] } }, When you specify `user_id` only, other entity fields default to null. Use wildcards to include them.
{ "created_at": { "gte": "2025-03-01T00:00:00Z" } } </Callout>
] }
```
### 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"] }
] }
```
---
## Troubleshooting ## 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 <Accordion title="ne operator returns too much">
{ "AND": [ { "user_id": "u1" }, { "agent_id": "*" } ] } **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 <Accordion title="Date range between two dates">
{ "AND": [ { "agent_id": "*" }, { "agent_id": { "ne": "a1" } } ] } **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?" <Accordion title="Metadata filter not working">
**Solution**: Match top-level metadata keys exactly:
Use `icontains`. ```python
{"metadata": {"source": "email"}}
```json ```
{ "AND": [ { "keywords": { "icontains": "receipt" } } ] } </Accordion>
``` </AccordionGroup>
### "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": "*" } ] }
```
---
## FAQ ## 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?** <Accordion title="Can I nest AND/OR?">
```python
No—equality is the default. `{ "user_id": "u1" }` is enough. {
"AND": [
**Q: Does `ne` include NULLs?** {"user_id": "user_123"},
{"OR": [
Yes. Use `{ "field": "*" }` together with `ne` if you need "present and not equal". {"categories": "finance"},
{"categories": "health"}
**Q: How do I search the memory text?** ]}
]
Use `keywords` with `contains` or `icontains`. }
```
**Q: Can I filter nested metadata keys?** </Accordion>
</AccordionGroup>
Currently target **top-level** keys as shown: `{ "metadata": { "foo": "bar" } }`.
+1 -1
View File
@@ -119,7 +119,7 @@ Walk through a real request/response. Include sample payloads and highlight nota
## Best practices ## Best practices
- Keep criteria minimal—overfiltering hurts recall. - 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 */} {/* DEBUG: verify CTA targets */}