Now let me check if `MongoDatabase` has an `upsert` method:


Grep

function upsert|function updateOne|function replaceOne


No matches found


192:    public function insert(string $collection, array $data): ?string
227:    public function insertOrUpdate(string $collection, array $data, array $uniqueFields = ['id']): ?string
288:    public function update(string $collection, array $filter, array $data): int
316:    public function delete(string $collection, array $filter): int
341:    public function findAll(string $collection, array $filter = [], array $options = []): array
371:    public function findOne(string $collection, array $filter): ?array


There's `insertOrUpdate` — let me check its signature:


   227→    public function insertOrUpdate(string $collection, array $data, array $uniqueFields = ['id']): ?string
   228→    {
   229→        if (!$this->available) {
   230→            return null;
   231→        }
   232→
   233→        try {
   234→            $coll = $this->getCollection($collection);
   235→
   236→            // Build filter from unique fields
   237→            $filter = [];
   238→            foreach ($uniqueFields as $field) {
   239→                if (isset($data[$field])) {
   240→                    $filter[$field] = $data[$field];
   241→                }
   242→            }
   243→
   244→            if (empty($filter)) {
   245→                // No unique fields found, just insert
   246→                return $this->insert($collection, $data);
   247→            }
   248→
   249→            // Add/update timestamps
   250→            $data['_updated_at'] = new UTCDateTime();
   251→
   252→            // Store MySQL ID if present
   253→            if (isset($data['id'])) {
   254→                $data['mysql_id'] = $data['id'];
   255→            }
   256→
   257→            $result = $coll->updateOne(
   258→                $filter,
   259→                [
   260→                    '$set' => $data,
   261→                    '$setOnInsert' => ['_created_at' => new UTCDateTime()]
   262→                ],
   263→                ['upsert' => true]
   264→            );
   265→
   266→            if ($result->getUpsertedId()) {
   267→                return (string) $result->getUpsertedId();
   268→            }
   269→
   270→            // Return the matched document ID
   271→            $doc = $coll->findOne($filter);
   272→            return $doc ? (string) $doc['_id'] : null;
   273→
   274→        } catch (Exception $e) {
   275→            $this->logError("MongoDB insertOrUpdate failed on {$collection}: " . $e->getMessage());
   276→            return null;
   277→        }
   278→    }
   279→
   280→    /**
   281→     * Update documents
   282→     *
   283→     * @param string $collection Collection name
   284→     * @param array $filter Filter criteria
   285→     * @param array $data Data to update
   286→     * @return int Number of modified documents
   287→     */
   288→    public function update(string $collection, array $filter, array $data): int
   289→    {
   290→        if (!$this->available) {
   291→            return 0;

    public function insertOrUpdate(string $collection, array $data, array $uniqueFields = ['id']): ?string
    {
        if (!$this->available) {
            return null;
        }

        try {
            $coll = $this->getCollection($collection);

            // Build filter from unique fields
            $filter = [];
            foreach ($uniqueFields as $field) {
                if (isset($data[$field])) {
                    $filter[$field] = $data[$field];
                }
            }

            if (empty($filter)) {
                // No unique fields found, just insert
                return $this->insert($collection, $data);
            }

            // Add/update timestamps
            $data['_updated_at'] = new UTCDateTime();

            // Store MySQL ID if present
            if (isset($data['id'])) {
                $data['mysql_id'] = $data['id'];
            }

            $result = $coll->updateOne(
                $filter,
                [
                    '$set' => $data,
                    '$setOnInsert' => ['_created_at' => new UTCDateTime()]
                ],
                ['upsert' => true]
            );

            if ($result->getUpsertedId()) {
                return (string) $result->getUpsertedId();
            }

            // Return the matched document ID
            $doc = $coll->findOne($filter);
            return $doc ? (string) $doc['_id'] : null;

        } catch (Exception $e) {
            $this->logError("MongoDB insertOrUpdate failed on {$collection}: " . $e->getMessage());
            return null;
        }
    }

    /**
     * Update documents
     *
     * @param string $collection Collection name
     * @param array $filter Filter criteria
     * @param array $data Data to update
     * @return int Number of modified documents
     */
    public function update(string $collection, array $filter, array $data): int
    {
        if (!$this->available) {
            return 0;


I need to replace my `upsert` calls with `insertOrUpdate`. Let me fix that:


Edit

$ctxMongo->upsert('ai_contact_memory',
                            ['contact_id' => $chatContactId],
                            [
                                'contact_id' => $chatContactId,
                                'contact_email' => $ctxContact['email'] ?? '',
                                'memories' => $memories,
                                'updated_at' => date('Y-m-d H:i:s'),
                            ]
                        );

$ctxMongo->insertOrUpdate('ai_contact_memory', [
                                'contact_id' => $chatContactId,
                                'contact_email' => $ctxContact['email'] ?? '',
                                'memories' => $memories,
                                'updated_at' => date('Y-m-d H:i:s'),
                            ], ['contact_id']);