2012-02-15 8 views
12

PHP PECL拡張を使用してMongoDBを試していますが、特定の更新クエリが機能するのが難しいです。私は小柄な答えを求めて周りを探しました。

$m = new Mongo; 
$collection = $m->testdb->testcollection; 

$collection->insert(array(
    0, 1, 1, 2, 3, 5 
)); 

findOneと、次のようにレコードが表示されますvar_dumpを使用した:私は$setを使用して更新したいとき

array 
    '_id' => 
    object(MongoId)[6] 
     public '$id' => string '4f3bde65a1f7a0315b000000' (length=24) 
    0 => int 0 
    1 => int 1 
    2 => int 1 
    3 => int 2 
    4 => int 3 
    5 => int 5 

問題が来る

私は基本的なコレクションを作成しました。私は100

$obj = $collection->findOne(); 

$collection->update(
    array('_id' => $obj['_id']), 
    array('$set' => array(0 => 100)) 
); 
再フェッチレコードはそれ ままであることを示している

を評価するために、フィールド0を更新したいここでPHPマニュアル

SQL to Mongo Cheat Sheetの底部に向かって示すマッピングに私のクエリを基づかています変更なし

私は_idと間違って何かをしていた場合、私は単純に一つのフィールドを更新していない、新しい値でレコード全体を交換するにもかかわらず、しかし、次の更新クエリ作業を行い、不思議をしました。

$collection->update(
    array('_id' => $obj['_id']), 
    array(0 => 100) 
); 

オブジェクトのダンプ:

array 
    '_id' => 
    object(MongoId)[7] 
     public '$id' => string '4f3bde65a1f7a0315b000000' (length=24) 
    0 => int 100 

誰かが私が間違っているのかを指し示してくださいすることができ、そしてどのように適切に$setを使用します。私はそれが明らかであると確信して、私はそれの上に目の第二のペアが必要です。

多くのありがとうございます。

+0

はこの作品行います '配列( '$セット' =>配列=> 100(1))'? –

+0

@yi_H:**は**働いています。フィールド '1'は更新されますが、なぜフィールド '0'では機能しませんか? – Leigh

答えて

11

私はこれがなぜ起こるかについていくつかの調査を行っています。そして、私はこの問題を「修正」する方法を見つけることができないと思います。

JavaScriptは、配列と結合配列/オブジェクトの間に違いがあります。 PHPは配列とオブジェクトの違いがあります。 PHPの場合、連想配列は配列であり、JavaScriptではオブジェクトです。

PHPドライバが配列をJSONオブジェクトに変換する必要がある場合、配列が次のいずれかであるかどうかを判断しようとします。0から始まる順番に番号が付けられたキーを持つ通常の配列。または連想配列。現在の実装では、順番に番号が付けられた配列を0から始まる配列とみなします。通常の配列にはのキーが含まれていません。これが問題です。ドライバが通常の配列を見る状況では、BSONにサーバに送信するフィールド名情報がないため、サーバはフィールドを更新できません。

既存のコードを壊さずにこの動作を変更する方法は考えられません。したがって、数値のフィールド名が必要な場合は、「メイン文書」にstdClassオブジェクトを使用する必要があります。また、あなたが埋め込まれた文書にこれらのキーを押した後、更新できます。

 
<?php 
$m = new Mongo; 
$collection = $m->demo->testcollection; 

$collection->insert(array(
    "_id" => 'bug341', 
    'data' => array(0, 1, 1, 2, 3, 5) 
)); 

$obj = $collection->findOne(); 

$update = array('data.0' => 'zero int'); 

$collection->update(
    array('_id' => 'bug341'), 
    array('$set' => $update) 
); 


$obj = $collection->findOne(); 
var_dump($obj); 
?> 
0

mongodbで有効なフィールド名として数字を使用することはできません。実際に実装されている方法は、引用符でフィールド "0"を入れてみてください。 yi_Hからのコメントに基づいて各種のテストを実行した後

+0

'array( '$ set' =>配列( '0' => 100))'は同じ結果を持ち、フィールド '0'は更新されません。 – Leigh

+2

php配列キーは文字列です... –

9

、と私は、次を発見したnnythmから答えます。次

$collection->update(
    array('_id' => $obj['_id']), 
    array('$set' => $updateObj) 
); 

がまったく動作しません:

  • $updateObj = array(0 => 100);
  • $updateObj = array('0' => 100);

は、これらの作業を行う

すべての場合において、私は、この共通のコードを使用しています:

  • $updateObj = array(1 => 100);
  • $updateObj = array('1' => 100);

MongoのPHPドキュメントの一部をグーグル及び読み出しのビットの後、私は、オブジェクトの代わりに配列を使用することができるが見つかりました。だから私はこれを試しました:

$updateObj = new stdClass; 
$updateObj->{0} = 100; 

この作品!

しかし、私は理由を見つけることができませんでした...

編集:MongoCollection->update方法は、以下を実行

Mongoの拡張ソースコードを突っつい

、bufがありますすでにポインタであり、newobjはzval(クエリの2番目のパラメータ)です。 HASH_Pは、配列かオブジェクトかに応じて、エンコーディングのためにzvalの正しいプロパティを返します。

zval_to_bson(buf, HASH_P(newobj), NO_PREP TSRMLS_CC) 

bson_encode機能は、機能面で同じです。 bufポインタとzval z。

zval_to_bson(&buf, HASH_P(z), 0 TSRMLS_CC); 

私は以下のテストを行った。

$updateObj = new stdClass; 
$updateObj->{0} = 100; 

$one = bson_encode($updateObj); 

$updateObj = array(0 => 100); 

$two = bson_encode($updateObj); 

var_dump($one === $two); 

出力は、アレイ内のフィールド名のために働いていない理由0損失ではまだtrue

です。

編集2:

さらなる実験は0の名前のフィールドが(配列のみ、オブジェクトが微細である)更新に含まれる場合ない更新は、任意のフィールド上で実行されていないことを示している

例:

$updateObj = array(
    '1' => 200 
); 

製作所、フィールド1が更新されます。

$updateObj = array(
    '0' => 100, 
    '1' => 200 
); 

ない仕事、どちらのフィールド0または1が更新されてい。

私はバグレポートを提出するつもりだと思います。

+0

は確かにバグのようです - 上記のような詳細をPHPドライバ(https://jira.mongodb.org/browse/PHP)に提出すれば私は確信していますクリスティーナ&カンパニーはすぐに修正をノックアウトします:) –

+0

@AdamC:アー、彼らは彼ら自身の問題トラッカーを持っています。私はすでにPECLパッケージ(PHPバグでは)(https://bugs.php.net/bug.php?id=61103)のレポートを提出しましたが、これらのことを複製することは嫌いですが、自分のシステムはもっと活発になっているようです。 – Leigh

+0

はい、正式にサポートされているすべてのドライバーは、JongのMongoDB.orgサイトで独自のトラッカーを持っています。パッケージのバグを見つけられない場合は、そのバグを参照してパッケージのバグを参照してください。ああ、詳細はこちら、この質問/回答にリンクするのは悪い考えではありません:) –

-1
we can update record in mongo db using php example below:- 

$m = new MongoClient(); 
    echo "Connection to database successfully"; 
    $db = $m->unified; 
     $collection = $db->profile; 

$document = array( 
        "name" => $_REQUEST['name'], 
        "email" => $_REQUEST['email'], 
        "age" => $_REQUEST['age'], 
        "address" => $_REQUEST['address'], 
        "comment"=> $_REQUEST['comment'] 

       ); 

       // print_r($document); die; 
      //echo $_REQUEST['pfid']; 
      $filter=array('_id'=>new MongoID($_REQUEST['pfid'])); 
      $update=array('$set'=>$document); 
    $collection->update($filter, $update); 
関連する問題