2017-07-07 63 views
0

我试过这样做了很多种方式,从updateOne,findOneAndUpdateinsert甚至试过bulkWrite没有成功。

我所做的是我有两个集合的用户集合和image_upload集合。我将用户个人资料图像存储在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',因此不需要再次尝试“投射”这个值。所以你应该只是'['$''=> [“personal.profile_id”=> $ ids]]'。此外,“复数”的命名不是很清楚,它应该只是一个单数值。而对于“推送数组”,如果这是意图的话,你可以使用['$ each'](https://docs.mongodb.com/manual/reference/operator/update/each/)修饰符。 –

回答

1

对于需要数组类型的$push运算符没有解决方法。不幸的是,这将需要迁移users集合中的文档。这样做将在下面讨论线程一些途径:

另外,如果你不想在迁移所有users文件一次,你可以有代码按顺序执行两个findOneAndUpdate()操作。第一个操作可以使用$type仅匹配{ "personal.profile_id": { $type: "string" }}的文档,然后使用$set分配最近的图像ID。然后第二个操作可以将文档与array type相匹配,并使用$push策略(请注意,$type不能用于检测数组字段)。然后调用代码会期望这些操作中的一个实际查找并更新文档(如果不是这种情况,请考虑记录错误)。这种方法将允许您开始为已迁移文档收集旧映像ID,但继续为未迁移文档覆盖该字段。根据您所提供的代码


另外一个观察:

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

$oid看起来像extended JSON语法的对象ID。这既不是更新操作员也不是在BSON文档中使用的有效密钥。试图通过蒙戈shell执行此更新将产生以下服务器端错误:

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

如果你只着眼于对象ID推到数组,下面应该是足够了:

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