sql >> データベース >  >> NoSQL >> MongoDB

マングース:挿入されたドキュメントが重複しているかどうかを検出し、重複している場合は既存のドキュメントを返します

    あなたのコードはいくつかのエラーケースを処理せず、間違ったfindを使用していますが 機能、一般的なフローはあなたがやりたい仕事を与える典型的なものです。

    1. 重複以外のエラーがある場合、コールバックは呼び出されません。これにより、NodeJsアプリケーションでダウンストリームの問題が発生する可能性があります
    2. findOneを使用します findではなく キーが一意である場合、結果は1つだけになるためです。それ以外の場合は、配列を返します。
    3. コールバックが従来のerrorを予期していた場合 最初の引数として、コールバックをfindOneに直接渡すことができます 匿名関数を導入するのではなく、関数。
    4. findOneAndUpdateもご覧ください。 最終的には、最終的なスキーマとロジックがどうなるかによって異なります。

    前述のように、findOneAndUpdateを使用できる場合があります 、ただし追加費用がかかります。

    function save(id, title, callback) {
        Value.findOneAndUpdate(
           {id: id, title: title}, /* query */
           {id: id, title: title}, /* update */
           { upsert: true}, /* create if it doesn't exist */
           callback);
    }
    

    もちろんコールバックはまだありますが、重複が見つかった場合はデータが再度書き込まれます。それが問題であるかどうかは、実際にはユースケースに依存します。

    私はあなたのコードを少しクリーンアップしました...しかしそれは本当に非常に単純で、コールバックは明確でなければなりません。 callback この関数は、常に新しく保存されたドキュメントまたは重複として一致したドキュメントのいずれかを受け取ります。 saveNewValueを呼び出す関数の責任です エラーをチェックして適切に処理します。エラーの種類に関係なくコールバックが呼び出され、常に一貫した方法で結果とともに呼び出されることを確認した方法もわかります。

    function saveNewValue(id, title, callback) {
        if (!callback) { throw new Error("callback required"); }
        var thisValue = new models.Value({
            id:id,
            title:title //this is a unique value
        });
    
        thisValue.save(function(err, product) {
            if (err) {
                if (err.code === 11000) { //error for dupes
                    return models.Value.findOne({title:title}, callback);
                }            
            }    
            callback(err, product);
        });
    }
    

    または、promise を使用することもできます。 パターン。この例では、when.js を使用しています。 。

    var when = require('when');
    
    function saveNewValue(id, title) {
        var deferred = when.defer();
    
        var thisValue = new models.Value({
            id:id,
            title:title //this is a unique value
        });
    
        thisValue.save(function(err, product) {
            if (err) {
                if (err.code === 11000) { //error for dupes
                    return models.Value.findOne({title:title}, function(err, val) {
                        if (err) {
                            return deferred.reject(err);
                        }
                        return deferred.resolve(val);
                    });
                }
                return deferred.reject(err);
            }
            return deferred.resolve(product);
        });
    
        return deferred.promise;
    }
    
    saveNewValue('123', 'my title').then(function(doc) {
        // success
    }, function(err) {
        // failure
    });
    


    1. MongoDB:MongoDBシェルでコレクションのすべてのレコードを削除する方法は?

    2. openshiftのnodejsとmongodbでPOSTできません

    3. Meteorは、別のドロップダウンが選択されたときにドロップダウンを動的にフィルタリングします

    4. 既存のデータベースの最初の文字を大文字にするMongoDBクエリ