final protected function doUpsert($scn, array $kvs)
    {
        $upsertKey = isset($kvs['external']) ? 'external' : 'legacy';
        $upsertNs  = 'legacy' === $upsertKey ? 'source' : 'namespace';
        $upsertId  = 'legacy' === $upsertKey ? 'id' : 'identifier';

        $update = ['$set' => $kvs];
        if (!isset($kvs[$upsertKey][$upsertId]) || !isset($kvs[$upsertKey][$upsertNs])) {
            throw new Exception\UpsertException(sprintf('%s.%s or %s.%s was not specified, cannot upsert!', $upsertKey, $upsertId, $upsertKey, $upsertNs));
        }

        if (!isset($kvs['_id'])) {
            $id = $this->generateId($scn);
            if (null !== $id) {
                $update['$setOnInsert'] = ['_id' => $id];
            }
        }

        $query = [
            sprintf('%s.%s', $upsertKey, $upsertId) => $kvs[$upsertKey][$upsertId],
            sprintf('%s.%s', $upsertKey, $upsertNs) => $kvs[$upsertKey][$upsertNs],
        ];

        $r = $this->getCollectionForModel($scn)->update($query, $update, ['upsert' => true]);

        if (true === $r['updatedExisting']) {
            $id = $this->getCollectionForModel($scn)->findOne($query, ['_id'])['_id'];
            $kvs['_id'] = $id;
        } else {
            if (!isset($kvs['_id'])) {
                $kvs['_id'] = $r['upserted'];
            }
        }
        return $kvs;
    }
final protected function doUpsert($scn, array $kvs)
    {
        $upsertKey = isset($kvs['external']) ? 'external' : 'legacy';
        $upsertNs  = 'legacy' === $upsertKey ? 'source' : 'namespace';
        $upsertId  = 'legacy' === $upsertKey ? 'id' : 'identifier';

        $update = ['$set' => $kvs];
        if (!isset($kvs[$upsertKey][$upsertId]) || !isset($kvs[$upsertKey][$upsertNs])) {
            throw new Exception\UpsertException(sprintf('%s.%s or %s.%s was not specified, cannot upsert!', $upsertKey, $upsertId, $upsertKey, $upsertNs));
        }

        if (!isset($kvs['_id'])) {
            $id = $this->generateId($scn);
            if (null !== $id) {
                $update['$setOnInsert'] = ['_id' => $id];
            }
        }

        $query = [
            sprintf('%s.%s', $upsertKey, $upsertId) => $kvs[$upsertKey][$upsertId],
            sprintf('%s.%s', $upsertKey, $upsertNs) => $kvs[$upsertKey][$upsertNs],
        ];

        $r = $this->getCollectionForModel($scn)->update($query, $update, ['upsert' => true]);

        if (true === $r['updatedExisting']) {
            $id = $this->getCollectionForModel($scn)->findOne($query, ['_id'])['_id'];
            $kvs['_id'] = $id;
        } else {
            if (!isset($kvs['_id'])) {
                $kvs['_id'] = $r['upserted'];
            }
        }
        return $kvs;
    }
final protected function doUpsert ( $ scn , array $ kvs ) { $ upsertKey = isset ( $ kvs [ 'external' ] ) ? 'external' : 'legacy' ; $ upsertNs = 'legacy' === $ upsertKey ? 'source' : 'namespace' ; $ upsertId = 'legacy' === $ upsertKey ? 'id' : 'identifier' ; $ update = [ '$set' => $ kvs ] ; if ( ! isset ( $ kvs [ $ upsertKey ] [ $ upsertId ] ) || ! isset ( $ kvs [ $ upsertKey ] [ $ upsertNs ] ) ) { throw new Exception \ UpsertException ( sprintf ( '%s.%s or %s.%s was not specified, cannot upsert!' , $ upsertKey , $ upsertId , $ upsertKey , $ upsertNs ) ) ; } if ( ! isset ( $ kvs [ '_id' ] ) ) { $ id = $ this -> generateId ( $ scn ) ; if ( null !== $ id ) { $ update [ '$setOnInsert' ] = [ '_id' => $ id ] ; } } $ query = [ sprintf ( '%s.%s' , $ upsertKey , $ upsertId ) => $ kvs [ $ upsertKey ] [ $ upsertId ] , sprintf ( '%s.%s' , $ upsertKey , $ upsertNs ) => $ kvs [ $ upsertKey ] [ $ upsertNs ] , ] ; $ r = $ this -> getCollectionForModel ( $ scn ) -> update ( $ query , $ update , [ 'upsert' => true ] ) ; if ( true === $ r [ 'updatedExisting' ] ) { $ id = $ this -> getCollectionForModel ( $ scn ) -> findOne ( $ query , [ '_id' ] ) [ '_id' ] ; $ kvs [ '_id' ] = $ id ; } else { if ( ! isset ( $ kvs [ '_id' ] ) ) { $ kvs [ '_id' ] = $ r [ 'upserted' ] ; } } return $ kvs ; }
Handles a single document upsert

@param   string  $scn    The model type
@param   array   $kvs    The model's keyValues.
@return  array   The upserted modelValues
Handles a single document upsert