symfony/ai-mongo-db-message-store
MongoDB message store integration for Symfony AI Chat. Persist and retrieve chat conversations using the MongoDB PHP library, with support for creating and managing collections. Useful for durable chat history storage in MongoDB-backed Symfony apps.
composer require symfony/ai-chat symfony/ai-mongo-db-message-store mongodb/mongodb
config/services.yaml (Symfony) or config/mongodb.php (Laravel):
# config/packages/ai.yaml (Symfony)
framework:
ai:
message_store: mongodb
mongodb:
uri: 'mongodb://user:pass@host:port/db'
collection: 'ai_chat_messages'
use MongoDB\Client;
$client = new Client('mongodb://user:pass@host:port/db');
$client->selectDatabase('db')->createCollection('ai_chat_messages');
use Symfony\Component\AI\Chat\MessageStore\MongoDbMessageStore;
use Symfony\Component\AI\Chat\Message;
$store = new MongoDbMessageStore($client->selectDatabase('db'));
$store->save(new Message('user', 'Hello!'));
$messages = $store->findByConversationId('conv_123');
symfony/dependency-injection for container integration.// Laravel Service Example
public function handleChatRequest(string $conversationId, string $userInput): array
{
$store = app(MongoDbMessageStore::class);
$messages = $store->findByConversationId($conversationId);
$response = $this->callSymfonyAIChat($userInput, $messages);
$store->save(new Message('ai', $response));
return ['response' => $response, 'history' => $messages];
}
// TTL Index Setup (via MongoDB CLI or PHP)
$collection->createIndex(['timestamp' => 1], ['expireAfterSeconds' => 2592000]); // 30 days
// Laravel Route
Route::post('/chat', function (Request $request) {
$response = Http::post('http://symfony-ai-service/api/chat', $request->all());
return $response->json();
});
// Laravel Service Provider
public function register()
{
$this->app->singleton(MongoDbMessageStore::class, function ($app) {
$client = new Client(config('mongodb.connection'));
return new MongoDbMessageStore($client->selectDatabase(config('mongodb.database')));
});
}
Symfony\Component\AI\Chat\Event\MessageSentEvent for post-processing:
public function handle(MessageSentEvent $event)
{
// Log, analyze, or sync to CRM
}
$text search for full-text queries:
$messages = $store->findBy([
'conversationId' => 'conv_123',
'text' => ['$text' => ['$search' => 'urgent']]
]);
class ResilientMongoDbMessageStore implements MessageStoreInterface
{
public function __construct(
private MongoDbMessageStore $primary,
private ?MessageStoreInterface $fallback = null
) {}
public function save(Message $message)
{
try {
$this->primary->save($message);
} catch (\Exception $e) {
$this->fallback?->save($message);
}
}
}
Driver Conflicts:
mongodb/mongodb (v2.0+) vs. jenssegers/mongodb (Laravel’s legacy driver).mongodb/mongodb and update Laravel’s MongoDB config:
// config/mongodb.php
'connections' => [
'default' => [
'driver' => 'mongodb',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', 27017),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'options' => [
'typeMap' => ['root' => 'array', 'document' => 'array'], // Critical for Symfony serialization
],
],
],
Serialization Mismatches:
serializer may conflict with Laravel’s JSON handling.# config/packages/serializer.yaml
framework:
serializer:
mapping:
paths: ['%kernel.project_dir%/config/serializer']
ignore_annotations: true
Missing Indexes:
conversationId or timestamp.$collection->createIndex(['conversationId' => 1, 'timestamp' => -1]);
No Schema Validation:
spatie/laravel-mongodb-schema):
use Spatie\LaravelMongoDbSchema\Schema;
Schema::create('ai_chat_messages', function (Blueprint $collection) {
$collection->index('conversationId');
$collection->index('timestamp');
$collection->required('userId');
$collection->required('role'); // 'user' or 'ai'
$collection->required('content');
});
Symfony-Specific Assumptions:
Message class; Laravel may need adapters.class LaravelMessage implements \Symfony\Component\AI\Chat\MessageInterface
{
public function __construct(
public string $role,
public string $content,
public ?string $id = null,
public ?string $conversationId = null,
public ?\DateTimeInterface $timestamp = null
) {}
}
$client->selectDatabase('db')->manage()->getLogger()->setCallback(function ($level, $message) {
error_log("[MongoDB] [$level] $message");
});
explain() to analyze slow queries:
$explanation = $collection->find(['conversationId' => 'conv_123'])->explain();
InvalidArgumentException: Check typeMap in MongoDB options (must match Symfony’s expectations).ClassNotFoundException: Ensure Symfony\Component\AI\Chat\Message is autoloaded or use the Laravel adapter.class ExtendedMongoDbMessageStore extends MongoDbMessageStore
{
public function saveWithMetadata(Message $message, array $metadata)
{
$document = $this->convertMessageToDocument($message);
$document['metadata'] = $metadata;
$this->collection->insertOne($document);
}
}
class EventfulMongoDbMessageStore extends MongoDbMessageStore
{
public function save(Message $message)
{
$result = parent::save($message);
event(new MessageStored($message, $result->getInsertedId()));
return $result;
}
}
public function bulkSave(iterable $messages)
{
$documents = array_map([$this, 'convertMessageToDocument'], $messages);
$this->collection->insertMany($documents);
}
4
How can I help you explore Laravel packages today?