2017-07-07 21 views
0

私はupdateOnefindOneAndUpdateからinsertまで多くの方法を試みましたし、bulkWriteでも成功しませんでした。

私が行ったことは、ユーザーコレクションとimage_uploadコレクションの2つのコレクションがあることです。私はユーザーがアップロードした他のすべての画像の横に、ユーザーのプロフィール画像をimage_uploadの中に保存します。

私がユーザーコレクションに保存するのは、ユーザーがアカウントを作成しているときにアップロードしたイメージと一致するimage_uploadコレクションのObjectIDです(プロファイルの編集を通じていつでも新しいプロファイルイメージをアップロードできます)。

私が望むのは、ObjectIdを更新する機能です。

フィールドpersonal.profile_idは配列である必要がありますが、ドキュメント内ではobjectId型です。ここにコードがあります。理想的には、文字列だけでなく、ObjectIDを持つことが理想です。

$db = static::db()->image_upload; 
        try { 
         $newdata = [ 
            "data"=> 
              [ 
              "url" => $publlic_url, 
              "type"=> $mimetype, 
              "date"=>new MongoDB\BSON\UTCDateTime(), 
              "profile_pic" => true 
              ], 
            "uid"=>New MongoDB\BSON\ObjectId($uid) 
            ]; 

         $oauth_update = $db->insertOne($newdata); 

         $view['newdata'] = $newdata; 
         } catch(MongoResultException $e) { 
          return $response->withStatus(200) 
           ->withHeader('Content-Type', 'application/json') 
           ->write($e->getDocument()); 

         } 

         $ids = $oauth_update->getInsertedId(); 

         $latest = $db->findOne(array("uid"=>New MongoDB\BSON\ObjectId($uid))); 

         // Check first, last and other personal details. 
         $db = static::db()->users; 
         try { 
         $newdata = ['$set' =>["personal.profile_id"=>New MongoDB\BSON\ObjectId($ids)]]; 

         $member_profile = $db->findOneAndUpdate(
          ['kst'=>New MongoDB\BSON\ObjectId($uid)], 
          ['$push' =>["personal.profile_id"=>['$oid'=>New MongoDB\BSON\ObjectId($ids)]]], 
          [ 
           'projection' => 
            [ 'personal' => 1 ], 
           "returnDocument" => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER 
          ]); 

         } catch(MongoResultException $e) { 
           echo $e->getCode(), " : ", $e->getMessage(), "\n"; 
           var_dump($e->getDocument()); 
           return $response->withStatus(200) 
           ->withHeader('Content-Type', 'application/json') 
           ->write(array('code'=>$e->getCode(), 'message'=>$e->getMessage)); 
         } 

         return $response->withStatus(200) 
         ->withHeader('Content-Type', 'application/json') 
         ->write(json_encode($member_profile)); 
+0

にですあなたが実際にここで尋ねていることは少し不明です。しかし、 '$ ids = $ oauth_update-> getInsertedId()'と表示される方法は、実際には 'ObjectId'を返さなければならないので、再度値をキャストする必要はありません。ですから、代わりに '['$ push' => [" personal.profile_id "=> $ ids]]'を使うべきです。また、 "複数"の命名は、単なる値でなければならないときには本当に明確ではありません。そして、 "配列をプッシュする"ためには、それが意図の場合は、['$ each'](https://docs.mongodb.com/manual/reference/operator/update/each/)修飾子を使用します。 –

答えて

1

は配列型を必要$pushオペレータのための回避策があります。残念ながら、これはusersコレクションのドキュメントを移行する必要があります。あなたはむしろ一度users内のすべてのドキュメントを移行したくない場合、あなたはコードを持つことができ、また

:そうするためのいくつかのアプローチは、以下のスレッドで議論されています2つのfindOneAndUpdate()操作を順番に実行します。最初の操作ではを使用して、{ "personal.profile_id": { $type: "string" }}の文書と一致させ、次に$setを使用して最新の画像IDを割り当てることができます。 2番目の操作では、文書をarray typeに一致させ、$push戦略を使用することができます(配列フィールドの検出には$typeを使用できません)。呼び出しコードは、これらの操作のうちの1つが実際に文書を見つけて更新することを期待しています(そうでない場合はエラーを記録することを検討してください)。この方法では、移行されたドキュメントの古いイメージIDの収集を開始できますが、移行されていないドキュメントのフィールドは上書きし続けます。あなたが提供されたコードに基づいて


もう一つの観察:

['$push' =>["personal.profile_id"=>['$oid'=>New MongoDB\BSON\ObjectId($ids)]]] 

$oidはObjectIDのためextended JSON構文のように見えます。これは、更新演算子でも、BSONドキュメントで使用する有効なキーでもありません。 mongoシェル経由でこのアップデートを実行しようとすると、次のサーバー側のエラーを得られます。

The dollar ($) prefixed field '$oid' 'personal.profile_id..$oid' is not valid for storage."

あなただけアレイ上のObjectIDをプッシュするために探している場合は、次のように十分なものでなければならない:

['$push' => ['personal.profile_id' => new MongoDB\BSON\ObjectId($ids)]] 
関連する問題