0

すべての注文にIDがある注文システムがあります。会計目的のために、増分番号で請求書を生成する方法が必要です。SQLデータベースを使用せずにこれを行う最良の方法は何ですか? ノードを使用してアプリケーションを実装しています。

4

2 に答える 2

3

http://www.mongodb.org/display/DOCS/How+to+Make+an+Auto+Incrementing+Field

最初のアプローチは、サイド ドキュメントにカウンターを保持することです。

現在の _id のカウンターをサイド ドキュメントのカウンター専用のコレクションに保持できます。次に、FindAndModify を使用してアトミックに ID を取得し、カウンターをインクリメントします。

もう 1 つのアプローチは、オプティミスティックにループし、衝突のエッジ ケースの ID を継続してインクリメントすることにより、重複キー エラー コード 11000 を処理することです。特定のコレクションへの同時書き込みが多い場合を除き、これはうまく機能します。

楽観的な同時実行の「存在しない場合は挿入」ループでそれを行うことができます。

ただし、そのページの警告に注意してください。

通常、MongoDB では、_id (またはその他のフィールド) に自動インクリメント パターンを使用しません。これは、大規模なデータベース クラスターではうまくスケールアップしないためです。代わりに、通常はオブジェクト ID を使用します。

その他の考慮事項:

  • タイムスタンプ- 一意の長いがインクリメントではない (エポックに基づく)
  • ハイブリッド アプローチ - アプリは必ずしも 1 つのストレージ オプションを選択する必要はありません。
  • 衝突を生成して処理する顧客、日付/時刻の部分などに基づいて、ID メカニズムを考え出します。スキームによっては、衝突の可能性がはるかに低くなります。必ずしも増加するわけではありませんが、一意であり、明確に定義された読み取り可能なパターンがあります。
于 2012-09-10T11:40:10.033 に答える
0

有効な解決策が見つからなかったため、node.js に「楽観的ループ」を実装して、自動インクリメントの整数 ID フィールドを取得しました。async モジュールを使用して while ループを実現します。

// Insert the document to the targetCollection. Use auto-incremented integer IDs instead of UIDs. 
function insertDocument(targetCollection, document, callback) {
    var keepRunning = true;
    var seq = 1;
    // $type 16/18: Integer Values
    var isNumericQuery = {$or : [{"_id" : { $type : 16 }}, {"_id" : { $type : 18 }}]};
    async.whilst(testFunction, mainFunction, afterFinishFunction);
    // Called before each execution of mainFunction(). Works like the stop criteria of a while function.
    function testFunction() { 
        return keepRunning; 
    }
    // Called each time the testFunction() passes. It is passed a function (next) which must be called after it has completed.
    function mainFunction(next) {
        findCursor(targetCollection, findCursorCallback, isNumericQuery, { _id: 1 });
        function findCursorCallback(cursor) {
            cursor.sort( { _id: -1 } ).limit(1);
            cursor.each(cursorEachCallback);
        }
        function cursorEachCallback(err, doc) {
            if (err) console.error("ERROR: " + err);
            if (doc != null) {
                seq = doc._id + 1;
                document._id = seq;
                targetCollection.insert(document, insertCallback);
            }
            if (seq === 1) {
                document._id = 1;
                targetCollection.insert(document, insertCallback);
            }
        }
        function insertCallback(err, result) {
            if (err) {
                console.dir(err);
            }
            else {
                keepRunning = false;
            }
            next();
        }
    }
    // Called once after the testFunction() fails and the loop has ended. 
    function afterFinishFunction(err) {
        callback(err, null);
    }
}

// Call find() with optional query and projection criteria and return the cursor object.
function findCursor(collection, callback, optQueryObject, optProjectionObject) {
    if (optProjectionObject === undefined) {
        optProjectionObject = {};
    }
    var cursor = collection.find(optQueryObject, optProjectionObject);
    callback(cursor);
}

で電話する

insertDocument(db.collection(collectionName), documentToSave, function() {if(err) console.error(err);});

于 2015-06-04T20:04:00.987 に答える