MongoDB PHP:如果不存在等效项,请插入


MongoDB PHP: Insert if not exists equivalent

我将MongoDB与PHP一起使用。为了为每个用户创建一个唯一的文档,我使用将用户名设置为唯一

$db->ensureIndex(array("username" => 1), array("unique" => 1, "dropDups" => 1));

但是,如果存在重复,则为用户返回的_id值是从未创建的记录的值,而不是数据库中已经存在的记录的id值。

以下是整个功能:

function register_user($username, $password, $first_name, $last_name, $email)
{    
$m = new Mongo();
$db = $m->users->details;
$db->ensureIndex(array("username" => 1), array("unique" => 1, "dropDups" => 1));
$user_doc = array( "username" => $username, "password" => $password, "first_name" => $first_name, "last_name" => $last_name, "email" => $email);
$db->insert($user_doc);
return $user_doc["_id"]; // here i return the _id
}

我该如何创建一个没有重复用户名的用户数据库?

编辑:

这是我的临时解决方案。我把它放在插件原来的位置。

try 
  {
      $db->insert($user_doc,array('safe'=>1));
  }
  catch ( MongoCursorException $e ) 
  {
      // if this did not work, we already have that user inside and want to get his _id
      $user = $db->findOne(array('username' => $username, 'password' => $password));
      return $user["_id"];
  }

如果我试着用安全选项插入它,它总是会死的。使用try-catch过程,我尝试插入,如果不起作用,请手动按用户名查找_id。我仍然对这个解决方案不满意,所以如果更熟练的MongoDB用户能给出一些建议,那就太好了。

首先,您总是需要try...catch$user_doc得到错误_id的原因很简单,因为驱动程序在将其发送到数据库之前创建了它。因此,即使插入失败,它仍然在文档中。

我该如何创建一个没有重复用户名的用户数据库?

首先,我会用用户名重写_id字段。为了方便起见,_id是自动生成的,但您可以在插入之前自行设置。

您仍然需要使用try...catch,但会出现特定的重复密钥错误。然后,您可以使用它来正确处理"该用户名已存在"的情况。

以下是我如何在不存在的情况下插入。

    $db->update(
            array('email' => $email),
            array('$setOnInsert' => array('email' => $email)),
            array('upsert' => true)
        );

这基本上只是在记录存在时更新("更新"到它已经设置的值,而$setOnInsert什么都不做),但如果它不存在,mongo会打乱一个新记录,然后创建新密钥并分配值。