MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Най-ефективният начин за промяна на стойността на поле на низ към неговия подниз

Най-ефективният начин да направите това е в предстоящото издание на MongoDB към момента на писане с помощта на $split оператор за разделяне на нашия низ като показан тук след това присвоете последния елемент в масива на променлива с помощта на $let променлив оператор и $arrayElemAt оператори.

След това използваме $switch оператор за извършване на обработка на логическо условие или оператор за случай спрямо тази променлива.

Условието тук е $gt което връща true, ако стойността съдържа "test" и в който случай в in израз разделяме този низ и просто връщаме $concat определена стойност на първия елемент в новоизчисления масив и - . Ако условието се изчисли като невярно, ние просто връщаме променливата.

Разбира се, в нашия 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 или Number след това актуализирайте документите си с помощта на $set оператор и bulkWrite() метод за максимална ефективност.

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);
}

Въпреки че заявката за агрегиране ще работи перфектно в MongoDB 3.4 или по-нова, нашият най-добър залог от MongoDB 3.2 назад е mapReduce с bulkWrite() метод.

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"];

results изглежда така:

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

От тук използвате предишния .forEach цикъл, за да актуализирате вашите документи.

От MongoDB 2.6 до 3.0 ще трябва да използвате вече отхвърления Bulk() API и свързаният с него метод, както е показано в моя отговор тук.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Заявка ISODate време в perl

  2. Геопространствена поддръжка в MongoDB

  3. Локален SQLite срещу отдалечен MongoDB

  4. Премахване чрез _id в конзолата на MongoDB

  5. mongodb-org е в конфликт с mongodb-10gen-сървър