52

私のプロジェクトでは、次のように、組織のグループのマングース ドキュメントを保持したいと考えています。

var groupSchema = Schema({
  name : { type : String },
  org : { type : Schema.Types.ObjectId, ref : 'Organization' },
  ...
  users : [{
    uid : { type : Schema.Types.ObjectId, ref : 'User' },
    ...
  }]
});

同じユーザーが同じグループに 2 回入らないようにしたい。これを行うには、users.uid を users 配列内で一意にする必要があります。uid に「unique : true」を指定しようとしましたが、うまくいきませんでした。追加のクエリやスキーマの分割を行わずに、mongoose または mongoDB でこれを行う方法はありますか?

編集: uid の以前の値を uid に変更しました: { type : Schema.Types.ObjectId, ref : 'User', index: {unique: true, dropDups: true} } しかし、これはまだ機能していないようです。

編集:これを達成する簡単な方法がないと仮定して、ユーザーが既にグループに属しているかどうかを確認する追加のクエリを追加しました。これは私には最も簡単な方法のようです。

4

2 に答える 2

133

配列フィールドの一意のインデックスは、同じ値がコレクション内の複数のドキュメントの配列に表示されないように強制しますが、同じ値が 1 つのドキュメントの配列に複数回表示されることを防ぎません。そのため、代わりに配列に要素を追加するときに一意性を確保する必要があります。

$addToSet値がまだ存在しない場合にのみ、演算子を使用して配列に値を追加します。

Group.updateOne({name: 'admin'}, {$addToSet: {users: userOid}}, ...

ただし、users配列に複数のプロパティを持つオブジェクトが含まれており、そのうちの 1 つだけで一意性を確保したい場合 (uidこの場合)、別のアプローチを取る必要があります。

var user = { uid: userOid, ... };
Group.updateOne(
    {name: 'admin', 'users.uid': {$ne: user.uid}}, 
    {$push: {users: user}},
    function(err, numAffected) { ... });

これは、 のどの要素のフィールドにもまだ存在しない$push場合にのみ更新が行われるように修飾します。したがって、動作を模倣しますが、 .user.uiduidusers$addToSetuid

于 2013-04-10T12:36:11.650 に答える