2010-12-05 11 views
8

存在しない場合にのみ、私は、各文書がmembersのアレイを有するlistsコレクションを持っています。 members配列の各要素は、emailプロパティ、作成dateプロパティ、およびその他のメタを持つドキュメントです。 members.emailにユニークなインデックスを設定して、同じメールを同じリストに2回入力しないようにしていますが、元のdateの値を保持したいと思います。残念ながら、$addToSetでも$pushもこれを実行していないようです。 $のプッシュを使用して

例:

$lists->update(array('_id' => $list['_id'], 'members.email' => array('$ne' => $email)), array('$push' => array('members' => array(
    'email' => $email, 
    'date' => new MongoDate(), 
    // etc. 
)))); 

と$ addToSetと

$lists->update(array('_id' => $list['_id']), array('$addToSet' => array('members' => array(
    'email' => $email, 
    'date' => new MongoDate(), 
    // etc. 
)))); 

どちらの例も、原因ユニークdate値(私は仮定)を新しいものに全体埋め込まれた文書を交換してください。 members.emailがまだ存在しない場合、または2つのコマンドでこれを行う必要がある場合は、$pushの「メンバー」ドキュメントのみが可能ですか?

また、membersparent_listのようなプロパティを持つ独自のコレクションに入れた方がスケーラビリティに優れていますか?

答えて

1

list_id、email、added_dateを保存するコレクションを持たない理由 次に、2つのキーlist_idとemailに一意のインデックスを作成します。それは同じLIST_IDと電子メール

あり埋め込まれることはありません文書で、レコードの挿入 を防止するであろう。 list_idでfind()を使用することができます

0

はい可能です。 mongoDB advanced queriesセクションの$ exists演算子を調べてください。メンバ電子メールが存在しない場合にのみ更新するために$ exists条件をwhere文に記述します。私の経験で

+1

私は$存在する、ほぼ正だが私が探しているソリューションではありません。 – Kevin

5

あなたのターゲット「のメンバーが」おそらく埋め込みオブジェクト(またはその作成後に1に変換)であるので、あなたが「$プッシュ」または「$ addToSet」であることができない理由。埋め込み配列にのみ$ push、$ pushAll、$ addToSetを使うことができます...

残念なことに私たちのために、PHPの開発者にとって、カーソルクエリは配列としてデータを返します。「メンバー」のようなものかどうかを調べる最良の方法ですmongoシェルでfind()を実行し、結果に中かっこ({}}か "[]")を探すことです。

これが役に立ちます。

0

IIUCは、埋め込まれたドキュメントを更新する(そのような場合)または(なしている場合)に挿入するかUpsertを使用してみてください。 thisも参照してください。親にドキュメントを埋め込むスケーラビリティ、その本当にケース依存に関する2つ目の質問あなたのよう

...は難しく更新を必要とし、大きなデータをフェッチしますが、フェッチクエリはカウント減らします。同じ電子メールのメンバーで文書をフィルタリングするクエリcondictionで

1

使用$ne

$lists->update(array('_id' => $list['_id'], 
        'members.email' => array('$ne' => $email)), 
       array('$addToSet' => array('members' => array(
        'email' => $email, 
        'date' => new MongoDate(), 
         // etc. 
)))); 
関連する問題