如何删除嵌入的文档

时间:2013-01-27 10:15:59

标签: php mongodb doctrine

我正在尝试从此结构中删除播放器。

{ "_id" : ObjectId( "51043d468ead0e0757000006" ),
  "active" : true,
  "created" : 1359232326,
  "difficulty" : 0,
  "map" : { "$ref" : "Map",
    "$id" : ObjectId( "5103c0228ead0e3764000000" ),
    "$db" : "fantasytd" },
  "mode" : "coop",
  "players" : [ 
    { "$ref" : "User",
      "$id" : ObjectId( "50d83abf038054b560000000" ),
      "$db" : "fantasytd" }, 
    { "$ref" : "User",
      "$id" : ObjectId( "50d83abf038054b560000000" ),
      "$db" : "fantasytd" }, 
    { "$ref" : "User",
      "$id" : ObjectId( "50d83abf038054b560000000" ),
      "$db" : "fantasytd" }, 
    { "$ref" : "User",
      "$id" : ObjectId( "50d83abf038054b560000000" ),
      "$db" : "fantasytd" } ],
 "title" : "testgame" }

我试过

$db->createQueryBuilder()
        ->update()
        ->field('id')->equals($gameId)
        ->field('players.$id')->equals($userId)
        ->pull('players.$.assets')
        ->getQuery()
        ->execute();

但是它不会起作用,遗憾的是Doctrine MongoDB的文档非常简洁:/

2 个答案:

答案 0 :(得分:0)

从技术上讲,由于阵列中的所有玩家都是相同的,所以应该这样做:

删除列表中的最后一位玩家:

db.coll.update({_id: ObjectId("51043d468ead0e0757000006")}, {$pop: {players: 1}})

删除列表中的第一个玩家:

db.coll.update({_id: ObjectId("51043d468ead0e0757000006")}, {$pop: {players: -1}})

(将“coll”替换为您的收藏名称。)

我认为这不是你想要的,所以我会添加一些玩家,这样就可以更容易地看到事情消失了:

db.coll.update({_id: ObjectId("51043d468ead0e0757000006")}, {$push: {players: {$ref: "User", $id: ObjectId("50d83abf038054b560000001")}}})
db.coll.update({_id: ObjectId("51043d468ead0e0757000006")}, {$push: {players: {$ref: "User", $id: ObjectId("50d83abf038054b560000002")}}})
db.coll.update({_id: ObjectId("51043d468ead0e0757000006")}, {$push: {players: {$ref: "User", $id: ObjectId("50d83abf038054b560000003")}}})

您可以使用此命令查看更改:

db.coll.find({_id: ObjectId("51043d468ead0e0757000006")}).pretty()

要删除数组中的第3个玩家,您可以先将玩家子文档设置为null,然后删除null:

db.coll.update({_id: ObjectId("51043d468ead0e0757000006")}, {$unset: {"players.3": 1}})
db.coll.update({_id: ObjectId("51043d468ead0e0757000006")}, {$pull: {players: null}})

或者删除具有特定$ ref和$ id的所有玩家:

db.coll.update({_id: ObjectId("51043d468ead0e0757000006")}, {$pull: {players: {$ref: "User", $id: ObjectId("50d83abf038054b560000000")}}})

答案 1 :(得分:0)

我结束了,在我的游戏文档中创建了一个删除方法。

  public function removePlayer($playerId)
  {
    foreach($this->players as $index => $player) {
      if($player->getId() == $playerId) {
        unset($this->players[$index]);
      }
    }
    return $this;
  }

调用此方法后,我只需执行flush()和magic!