2

次のように、Mongoose を使用して、MongoDB で一意でスパースになるスキーマの 2 つのフィールドにインデックスを作成しようとしています。

var ArraySchema = new Schema ({
    user_id: {type: mongoose.Schema.Types.ObjectId, ref:'User'},
    event_id: {type: mongoose.Schema.Types.ObjectId, ref:'Event'}
}, {_id:false});

ListSchema.index({user_id:1, event_id:1}, {sparse:true, unique:true});

次に、 User スキーマの配列で次のように使用されます。

var User = new Schema({
    arrayType1 : {
        type: [ArraySchema]
    },
    arrayType2 : {
        type: [ArraySchema]
    },
    arrayType3 : {
        type: [ArraySchema]
    }
    //More specifications for user schema...
});

ただし、フィールドを指定せずに複数のユーザーを保存しようとするとarray、重複するフィールドに対してエラーがスローされます。Mocha のエラーは次のようになりますarray.event_id_1 dup key {null, null}。このエラーをスローするコード セグメントの例は次のとおりです。

var user1, user2;

user1 = new User({
    username : 'username1',
    password : 'password'
});

user2 = new User({
    username : 'username2',
    password : 'password'
});

user1.save(function() {
    user2.save();
});

ArraySchema のフィールドを一意でスパースにする理由は次のとおりです。フィールドが指定されている場合array、配列に重複したオブジェクトを含めたくありません。ただし、arrayフィールドは必須ではないため、このフィールドを持っているユーザーが多数存在nullします。arrayType1明らかに、インデックス ( 、arrayType2、 )を必要とする複数のフィールドがあるため、フィールド レベルのインデックスは使用できませんarrayType3

4

1 に答える 1

1

少なくとも現時点では、このようなことはサポートされていないようです。別の方法は、これらのフィールドに複合インデックスを作成し、フィールドに新しい要素を追加するたびにuser.arrayType1.addToSet(). これがどのように機能するかの例を次に示します。

配列スキーマ:

var ArraySchema = new Schema ({
     user_id: {type: mongoose.Schema.Types.ObjectId, ref:'User'},
     event_id: {type: mongoose.Schema.Types.ObjectId, ref:'Event'}
}, {_id:false});

ListSchema.index({user_id:1, event_id:1});

ユーザースキーマ:

var User = new Schema({
    arrayType1 : {
        type: [ArraySchema]
    },
     arrayType2 : {
         type: [ArraySchema]
    },
    arrayType3 : {
        type: [ArraySchema]
    }
    //More specifications for user schema...
});

次に、通常どおり新しいユーザーを宣言できます (質問で行ったように)。ただし、arrayType1たとえば、新しい要素を に追加する場合は、次のコード行を使用して、まだ存在しない場合にのみ新しい要素に追加します。

user.arrayType1.addToSet({user_id : user2._id, event_id : event._id});
user.save(function(err, result) {
    //Callback logic.
};

whereuser2eventはコードの前半で定義され、db に保存されます。または、Mongoose の update 関数を次のように使用することもできます。

User.update({_id : user._id}, {
        $addToSet : {
            arrayType1 : {
                user_id : user2._id,
                event_id : event._id
            }
        }
    }, function(err) {
        //Callback logic.
    }
);
于 2014-11-12T21:19:00.960 に答える