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

文字列フィールドの値をその部分文字列に変更する最も効率的な方法

    これを行う最も効率的な方法は、 $ split を使用して、この記事の執筆時点でのMongoDBの次のリリースにあります。 文字列をここに表示 として分割する演算子 次に、 を使用して、配列の最後の要素を変数に割り当てます。 $ let 変数演算子と $ arrayElemAt 演算子。

    次に、 $ switchを使用します その変数に対して論理条件処理またはcaseステートメントを実行する演算子。

    ここでの条件は、 $ gtです。 値に"test"が含まれている場合はtrueを返します 、その場合は in その文字列を分割して、 $ concat> 新しく計算された配列の最初の要素と-の値 。条件がfalseと評価された場合は、変数を返すだけです。

    もちろん、caseステートメントでは、 $ indexOfCPを使用します。 -1を返します "test"が発生しなかった場合 。

    let cursor = db.collection.aggregate(
        [
            { "$project": { 
                "data": 1, 
                "version": { 
                    "$let": { 
                        "vars": { 
                            "v": { 
                                "$arrayElemAt": [
                                    { "$split": [ "$version", "." ] }, 
                                    -1
                                ]
                            }
                        }, 
                        "in": { 
                            "$switch": { 
                                "branches": [ 
                                    { 
                                        "case": { 
                                            "$gt": [ 
                                                { "$indexOfCP": [ "$$v", "test" ] },
                                                -1 
                                            ]
                                        }, 
                                        "then": { 
                                            "$concat": [ 
                                                "-", 
                                                "", 
                                                { "$arrayElemAt": [
                                                    { "$split": [ "$$v", "-" ] }, 
                                                    0 
                                                ]} 
                                            ]
                                        }
                                    }
                                ], 
                                "default": "$$v" 
                            }
                        }
                    }
                }
            }}
        ]
    )
    

    集計クエリは次のようなものを生成します:

    { "_id" : ObjectId("57a98773cbbd42a2156260d8"), "data" : 11, "version" : "32" }
    { "_id" : ObjectId("57a98773cbbd42a2156260d9"), "data" : 55, "version" : "-42" }
    

    ご覧のとおり、「バージョン」フィールドデータは文字列です。そのフィールドのデータ型が重要でない場合は、 $ outを使用するだけです。 結果を新しいコレクションに書き込むか、コレクションを置き換えるための集計パイプラインステージ演算子。

    { "out": "collection" }
    

    データを浮動小数点数に変換する必要がある場合、これを行う唯一の方法は、MongoDBが整数から文字列への変換を除いて、箱から出して型変換を行う方法を提供しないため、集計カーソルを繰り返すことです。オブジェクトを作成し、 parseFloat> または番号 次に、 $ setを使用してドキュメントを更新します 演算子と bullkWrite() 最大の効率のための方法。

    let requests = [];
    cursor.forEach(doc => { 
        requests.push({ 
            "updateOne": { 
                "filter": { "_id": doc._id }, 
                "update": { 
                    "$set": { 
                        "data": doc.data, 
                        "version": parseFloat(doc.version) 
                    },
                    "$unset": { "person": " " }
                } 
            } 
        }); 
        if ( requests.length === 1000 ) { 
            // Execute per 1000 ops and re-init
            db.collection.bulkWrite(requests); 
            requests = []; 
        }} 
    );
    
     // Clean up queues
    if(requests.length > 0) {
        db.coll.bulkWrite(requests);
    }
    

    集計クエリはMongoDB3.4以降で完全に機能しますが、MongoDB3.2以降の最善策は mapReduce bullkWrite()を使用 メソッド。

    var results = db.collection.mapReduce(
        function() { 
            var v = this.version.split(".")[2]; 
            emit(this._id, v.indexOf("-") > -1 ? "-"+v.replace(/\D+/g, '') : v)
        }, 
        function(key, value) {}, 
        { "out": { "inline": 1 } }
    )["results"];
    

    結果 次のようになります:

    [
        {
            "_id" : ObjectId("57a98773cbbd42a2156260d8"),
            "value" : "32"
        },
        {
            "_id" : ObjectId("57a98773cbbd42a2156260d9"),
            "value" : "-42"
        }
    ]
    

    ここから、以前のを使用します。 .forEach ドキュメントを更新するためにループします。

    MongoDB 2.6から3.0までは、廃止された Bulk( ) ここで回答 に示されているAPIとそれに関連するメソッド




    1. MongoDB:すべての一意のタグのリストを取得するための良い方法は何ですか?

    2. マングース-2dsphereインデックス-ハウツー

    3. javascriptを介してmongodbに設定されたセカンダリレプリカから読み取る

    4. $exprクエリ演算子が配列ドット表記で機能しないようです