ক্ষেত্রের ধরণ কীভাবে পরিবর্তন করবেন?


158

আমি মঙ্গো শেলের মধ্যে থেকে কোনও ক্ষেত্রের ধরণটি পরিবর্তন করার চেষ্টা করছি।

আমি এটি করছি ...

db.meta.update(
  {'fields.properties.default': { $type : 1 }}, 
  {'fields.properties.default': { $type : 2 }}
)

কিন্তু এটি কাজ করছে না!


যদি কেউ একইরকম পরিস্থিতিতে থাকে তবে আমি toStringকিছু নথির ক্ষেত্রে থাকি, আমি তৈরি / ব্যবহার করেছি এমন একটি ছোট প্রোগ্রাম এখানে
দীর্ঘ

উত্তর:


213

পরিবর্তন করার একমাত্র উপায় $typeডেটা হ'ল ডেটাটির সঠিক আপডেট রয়েছে এমন ডেটাতে একটি আপডেট সম্পাদন করা।

এই ক্ষেত্রে, দেখে মনে হচ্ছে আপনি $type 1 (ডাবল) থেকে 2 (স্ট্রিং) এ পরিবর্তন করার চেষ্টা করছেন ।

সুতরাং সহজেই ডিবি থেকে দস্তাবেজটি লোড করুন, কাস্ট সম্পাদন করুন ( new String(x)) এবং তারপরে আবার নথিটি সংরক্ষণ করুন।

আপনার যদি শেল থেকে প্রোগ্রামগতভাবে এবং সম্পূর্ণরূপে এটি করার দরকার হয় তবে আপনি find(...).forEach(function(x) {})সিনট্যাক্সটি ব্যবহার করতে পারেন ।


নীচে দ্বিতীয় মন্তব্যের জবাবে। badসংগ্রহের একটি নম্বর থেকে ক্ষেত্রটি পরিবর্তন করুন foo

db.foo.find( { 'bad' : { $type : 1 } } ).forEach( function (x) {   
  x.bad = new String(x.bad); // convert field to string
  db.foo.save(x);
});

1
উদাহরণের কোনও সম্ভাবনা - শেল থেকে ক্ষেত্রের ধরনটি স্ট্রিং (বা বিপরীতে) থেকে পরিবর্তন করা?
আলিস্টার বুলম্যান

30
ইনট 32-> স্ট্রিংয়ের ক্ষেত্রে new String(x.bad)0-সূচি-আইটেম x.badমানের সাথে স্ট্রিংয়ের সংগ্রহ তৈরি করে । ""+x.badসাইমন দ্বারা বর্ণিত ভেরিয়েন্টটি পছন্দসই হিসাবে কাজ করে
দাও

উপরের কোডটি ক্ষেত্রের ডেটাগুলিকে ডাবল স্ট্রিংয়ের পরিবর্তে ডাবল থেকে অ্যারে রূপান্তর করছে। আমার আসল তথ্য এই ফর্ম্যাটে ছিল: ৩.১ যেখানে সিমোন কোডটি আমার পক্ষে ভাল কাজ করছে
পঙ্কজ খুরানা

2
আমার এমন পরিস্থিতি হয়েছিল যেখানে আমাকে _id ক্ষেত্র রূপান্তর করতে হবে এবং অন্য সূচকের সাথে বিরোধ নয়:db.questions.find({_id:{$type:16}}).forEach( function (x) { db.questions.remove({_id:x._id},true); x._id = ""+x._id; db.questions.save(x); });
ম্যাট মোলনার

@ সুন্দরবোনস হ্যাঁ আপনি আপনার ডাটাবেস জুড়ে কোনও ক্ষেত্র পুনরায় লিখছেন, আপনি এটি যেভাবেই করেন না কেন এটি বড় বিষয়। আপনি যদি এসকিউএল ব্যবহার করেন এবং এটি একটি বড় টেবিল ছিল তবে আপনাকে সম্ভবত কিছুটা সময় নিতে হবে।
গেটস ভিপি

161

স্ট্রিং ফিল্ডটি পূর্ণসংখ্যায় রূপান্তর করুন:

db.db-name.find({field-name: {$exists: true}}).forEach(function(obj) { 
    obj.field-name = new NumberInt(obj.field-name);
    db.db-name.save(obj);
});

পূর্ণসংখ্যা ক্ষেত্রটিকে স্ট্রিংয়ে রূপান্তর করুন:

db.db-name.find({field-name: {$exists: true}}).forEach(function(obj) {
    obj.field-name = "" + obj.field-name;
    db.db-name.save(obj);
});

এটি দুর্দান্ত - আপনি কীভাবে জানেন যে আপনি কীভাবে স্ট্রিংকে ('1.23' এর মতো মুদ্রাটি) পূর্ণসংখ্যায় 123 তে রূপান্তর করবেন? আমি ধরে নিয়েছি যে আপনি এটি একটি ফ্লোট বা দশমিক হিসাবে পার্স করতে হবে, এটি 100 দ্বারা গুণিত করুন, তারপরে এটি একটি পূর্ণসংখ্যা হিসাবে সংরক্ষণ করুন, তবে এটি করার জন্য আমি সঠিক ডক্সটি খুঁজে পাচ্ছি না। ধন্যবাদ!
ব্রায়ান আর্মস্ট্রং

আসলে এই কাজ ভাল। তবে আমার কাছে মঙ্গয়েড ২.৪.০-স্থিতিশীল সহ একটি অ্যাপ্লিকেশন চলছে যার ক্ষেত্র যেমন ক্ষেত্র: গ্রাহক_কাউন্ট, প্রকার: পূর্ণসংখ্যা এবং বৈধতা যাচাইকরণের হিসাবে বৈধতা_সংখ্যকতা: গ্রাহক_কাউন্ট যা ভাল কাজ করছিল। এখন যখন আমি মঙ্গয়েডকে 3.0.16 এ আপগ্রেড করছি, যখন আমি একটি স্ট্রিংয়ের মান নির্ধারণ করি এটি স্বয়ংক্রিয়ভাবে এটিকে 0 এ রূপান্তর করে ত্রুটি ছাড়াই। আমি ভুল ডেটা অ্যাসাইনমেন্টে একটি ত্রুটি ফেলতে চাই, এই আচরণটি আমার জন্য অদ্ভুত turning
স্বপ্নিল চিনচোলকর

4
আমি এটি
চালিয়েছি

এবং যদি আপনার স্ট্রিং (বা "স্বাভাবিক" 32-বিট পূর্ণসংখ্যার) 64-বিট পূর্ণসংখ্যায় রূপান্তর করতে NumberLongহয় তবে এখানে হিসাবে ব্যবহার করুন:db.db-name.find({field-name : {$exists : true}}).forEach( function(obj) { obj.field-name = new NumberLong(obj.field-name); db.db-name.save(obj); } );
বোরিয়ান

এটি কাজ করে। এম্বেড থাকা নথির ক্ষেত্রগুলির মধ্যে কীভাবে ডেটাটাইপ পরিবর্তন করতে হবে তা আমি জানতে পারি
সংকর মুনিয়াপ্পা

43

স্ট্রিং থেকে ইন রূপান্তরের জন্য।

db.my_collection.find().forEach( function(obj) {
    obj.my_value= new NumberInt(obj.my_value);
    db.my_collection.save(obj);
});

স্ট্রিং জন্য ডাবল রূপান্তর।

    obj.my_value= parseInt(obj.my_value, 10);

ভাসার জন্য:

    obj.my_value= parseFloat(obj.my_value);


5
সাবধান , আমি Robomongo সঙ্গে এই পরীক্ষিত, এবং এই টাইপ 1 ফলে: ডবল। ব্যবহার করতে হয়েছিলnew NumberInt()
ড্যানিয়েল এফ

ড্যানিয়েল, আপনার সমাধান ঠিক নেই ... ডেভিডের সমাধান ঠিক আছে
রাজীব


15

শুরু করা Mongo 4.2, db.collection.update()একত্রিত পাইপলাইন গ্রহণ করতে পারে, অবশেষে নিজস্ব মানের উপর ভিত্তি করে কোনও ক্ষেত্রের আপডেটের অনুমতি দেয়:

// { a: "45", b: "x" }
// { a:  53,  b: "y" }
db.collection.update(
  { a : { $type: 1 } },
  [{ $set: { a: { $toString: "$a" } } }],
  { multi: true }
)
// { a: "45", b: "x" }
// { a: "53", b: "y" }
  • প্রথম অংশটি { a : { $type: 1 } }ম্যাচের ক্যোয়ারী:

    • এটি কোন নথিগুলি আপডেট করবে তা ফিল্টার করে।
    • এই ক্ষেত্রে, যেহেতু আমরা "a"স্ট্রিংয়ে রূপান্তর করতে চাই যখন এর মান দ্বিগুণ হয়, তাই এটি উপাদানগুলির সাথে মেলে যা "a"প্রকারের1 (ডাবল)।
    • এই টেবিলটি বিভিন্ন সম্ভাব্য প্রকারের প্রতিনিধিত্বকারী কোডগুলি সরবরাহ করে।
  • দ্বিতীয় অংশটি [{ $set: { a: { $toString: "$a" } } }]আপডেট সমষ্টি পাইপলাইন:

    • এই আপডেট কোয়েরিটি একত্রিত পাইপলাইন ব্যবহার করে তা নির্দেশ করে স্কোয়ার বন্ধনীগুলি নোট করুন।
    • $set একটি নতুন সমাহার অপারেটর (Mongo 4.2 ) যা এই ক্ষেত্রে একটি ক্ষেত্র পরিবর্তন করে if
    • এটিকে রূপান্তরিত করার "$set"মান হিসাবে সহজেই পড়া যায়"a""$a""$toString"
    • এখানে সত্যিই নতুন কী, Mongo 4.2নথিটি আপডেট করার সময় নিজেই তা উল্লেখ করতে সক্ষম হচ্ছেন : এর জন্য নতুন মান "a"বিদ্যমান মানের উপর ভিত্তি করে"$a"
    • এছাড়াও লক্ষ করুন "$toString"যেটি একটি নতুন সমষ্টি অপারেটর চালু হয়েছে Mongo 4.0
  • ভুলে যাবেন না { multi: true }, অন্যথায় কেবল প্রথম ম্যাচের ডকুমেন্ট আপডেট করা হবে।


ডবল থেকে স্ট্রিং যদি আপনার কাস্ট না হয় তবে আপনি চালু বিভিন্ন রূপান্তর অপারেটার মধ্যে পছন্দ আছে Mongo 4.0যেমন $toBool, $toInt...

এবং যদি আপনার লক্ষ্যযুক্ত ধরণের জন্য কোনও উত্সর্গীকৃত রূপান্তরকারী না থাকে তবে আপনি { $toString: "$a" }একটি $convertক্রিয়াকলাপের সাথে প্রতিস্থাপন করতে পারেন : { $convert: { input: "$a", to: 2 } }যেখানে এর সারণীতেto এই মানটি পাওয়া যাবে :

db.collection.update(
  { a : { $type: 1 } },
  [{ $set: { a: { $convert: { input: "$a", to: 2 } } } }],
  { multi: true }
)

1
db.collection.updateMany( { a : { $type: 1 } }, [{ $set: { a: { $toString: "$a" } } }] )- এটি multi : trueব্যবহার এড়ানো যায়updateMany
ভাসিম

1
2020 হিসাবে, $ রূপান্তরটি ব্যবহার করা এর জন্য সঠিক পদ্ধতি হওয়া উচিত কারণ এটি অনেক বেশি দক্ষ (এবং বুট করার জন্য সহজ ব্যবহারযোগ্য) হওয়া উচিত।
খলিল রাভান্না

10

সমস্ত উত্তর এখন পর্যন্ত forEach এর কিছু সংস্করণ ব্যবহার করে সমস্ত সংগ্রহ উপাদানগুলির ক্লায়েন্ট-সাইডের উপরে পুনরাবৃত্তি করে।

তবে, আপনি মোট পাইপলাইন এবং আউট স্টেজ ব্যবহার করে মংগোডিবি'র সার্ভার-সাইড প্রসেসিংটি ব্যবহার করতে পারেন :

আউট স্টেজ পরমাণুভাবে নতুন সংগ্রহের ফলাফলের সাথে বিদ্যমান সংগ্রহকে প্রতিস্থাপন করে।

উদাহরণ:

db.documents.aggregate([
         {
            $project: {
               _id: 1,
               numberField: { $substr: ['$numberField', 0, -1] },
               otherField: 1,
               differentField: 1,
               anotherfield: 1,
               needolistAllFieldsHere: 1
            },
         },
         {
            $out: 'documents',
         },
      ]);

2
আমি জানি না কেন এটি আরও বেশি উত্সাহিত হয় না। বড় ডেটা সেটগুলিতে সারি
ক্রিয়া

7

স্ট্রিংয়ের ক্ষেত্রের ক্ষেত্রকে তারিখের ক্ষেত্রে রূপান্তর করতে, আপনাকে লুপের মধ্যে find()পদ্ধতিটি ব্যবহার করে forEach()পদ্ধতি দ্বারা ফিরে আসা কার্সারটি পুনরায় করা দরকার , ক্ষেত্রটিকে একটি ডেট অবজেক্টে রূপান্তর করতে হবে এবং তারপরে $setঅপারেটরটি ব্যবহার করে ক্ষেত্রটি আপডেট করতে হবে ।

আপনি বাল্ক আপডেটের জন্য বাল্ক এপিআই ব্যবহার করার সুবিধা নিন যা আপনি আরও ভাল পারফরম্যান্সের প্রস্তাব দিচ্ছেন আপনি 1000 বলার ব্যাচে সার্ভারে অপারেশনগুলি প্রেরণ করবেন যা আপনাকে সার্ভারে প্রতিটি অনুরোধ প্রেরণ না করে আপনাকে আরও ভাল পারফরম্যান্স দেয় যা প্রতিবারে একবার 1000 অনুরোধ।

নীচে এই পদ্ধতির প্রদর্শন করে, প্রথম উদাহরণটি মোংগোডিবি সংস্করণগুলিতে উপলব্ধ বাল্ক এপিআই ব্যবহার করে >= 2.6 and < 3.2। এটি সংগ্রহের সমস্ত দস্তাবেজকে সমস্ত created_atক্ষেত্রকে তারিখের ক্ষেত্রে পরিবর্তন করে আপডেট করে:

var bulk = db.collection.initializeUnorderedBulkOp(),
    counter = 0;

db.collection.find({"created_at": {"$exists": true, "$type": 2 }}).forEach(function (doc) {
    var newDate = new Date(doc.created_at);
    bulk.find({ "_id": doc._id }).updateOne({ 
        "$set": { "created_at": newDate}
    });

    counter++;
    if (counter % 1000 == 0) {
        bulk.execute(); // Execute per 1000 operations and re-initialize every 1000 update statements
        bulk = db.collection.initializeUnorderedBulkOp();
    }
})
// Clean up remaining operations in queue
if (counter % 1000 != 0) { bulk.execute(); }

পরবর্তী উদাহরণটি নতুন মঙ্গোডিবি সংস্করণে প্রযোজ্য 3.2যা বাল্ক এপিআই-কে অবজ্ঞা করে এবং এপিএস ব্যবহার করে একটি নতুন সেট সরবরাহ করেছে bulkWrite():

var bulkOps = [];

db.collection.find({"created_at": {"$exists": true, "$type": 2 }}).forEach(function (doc) { 
    var newDate = new Date(doc.created_at);
    bulkOps.push(         
        { 
            "updateOne": { 
                "filter": { "_id": doc._id } ,              
                "update": { "$set": { "created_at": newDate } } 
            }         
        }           
    );     
})

db.collection.bulkWrite(bulkOps, { "ordered": true });

1
দুর্দান্ত উত্তর, বাল্ক পদ্ধতিটি আমার জন্য প্রায় 100x দ্রুত চালিত হয় যদিও এটি এখনও একটি সিঙ্ক্রোনাস কল হিসাবে উপস্থিত হয়।
ম্যাথু

3

বিন্যাস তৈরি না করে ইন্ট 32 কে স্ট্রিংয়ে মোঙ্গোতে রূপান্তর করতে কেবল আপনার সংখ্যায় "" যুক্ত করুন :-)

db.foo.find( { 'mynum' : { $type : 16 } } ).forEach( function (x) {   
  x.mynum = x.mynum + ""; // convert int32 to string
  db.foo.save(x);
});

3

মন্ডোডিবি-তে অবজেক্টের ধরণটি পরিবর্তন করতে আমাকে সত্যই কী সাহায্য করেছিল কেবলমাত্র এই সাধারণ লাইনটি, সম্ভবত এখানে উল্লেখ করার আগে ...:

db.Users.find({age: {$exists: true}}).forEach(function(obj) {
    obj.age = new NumberInt(obj.age);
    db.Users.save(obj);
});

ব্যবহারকারীরা আমার সংগ্রহ এবং বয়স হ'ল অবজেক্টটি যার পূর্ণসংখ্যার পরিবর্তে একটি স্ট্রিং ছিল (ইন্ট 32)।


1

আমাকে সংগ্রহের একাধিক ক্ষেত্রের ডেটাটাইপ পরিবর্তন করতে হবে, তাই নথি সংগ্রহের ক্ষেত্রে একাধিক ডেটা টাইপের পরিবর্তন করতে আমি নিম্নলিখিতটি ব্যবহার করেছি। একটি পুরানো প্রশ্নের উত্তর কিন্তু অন্যদের জন্য সহায়ক হতে পারে।

db.mycoll.find().forEach(function(obj) { 

    if (obj.hasOwnProperty('phone')) {
        obj.phone = "" + obj.phone;  // int or longint to string
    }

    if (obj.hasOwnProperty('field-name')) {
     obj.field-name = new NumberInt(obj.field-name); //string to integer
    }

    if (obj.hasOwnProperty('cdate')) {
        obj.cdate = new ISODate(obj.cdate); //string to Date
    }

    db.mycoll.save(obj); 
});

1
You can easily convert the string data type to numerical data type.
Don't forget to change collectionName & FieldName.
for ex : CollectionNmae : Users & FieldName : Contactno.

এই কোয়েরি চেষ্টা করুন ..

db.collectionName.find().forEach( function (x) {
x.FieldName = parseInt(x.FieldName);
db.collectionName.save(x);
});

1

স্ট্রোক থেকে মঙ্গো অবজেক্টে ডেমো পরিবর্তনের ক্ষেত্রের প্রকার মঙ্গু ব্যবহার করুন

 Post.find({}, {mid: 1,_id:1}).exec(function (err, doc) {
             doc.map((item, key) => {
                Post.findByIdAndUpdate({_id:item._id},{$set:{mid: mongoose.Types.ObjectId(item.mid)}}).exec((err,res)=>{
                    if(err) throw err;
                    reply(res);
                });
            });
        });

মঙ্গো অবজেক্টআইড যেমন শৈলীর অন্য একটি উদাহরণ

সংখ্যা, স্ট্রিং, বুলিয়ান আশা করি উত্তরটি অন্য কাউকে সহায়তা করবে।


0

আমি রূপান্তরটি ভাসতে স্ট্রিংয়ের জন্য এই স্ক্রিপ্টটি মঙ্গোদব কনসোলে ব্যবহার করি ...

db.documents.find({ 'fwtweaeeba' : {$exists : true}}).forEach( function(obj) { 
        obj.fwtweaeeba = parseFloat( obj.fwtweaeeba ); 
        db.documents.save(obj); } );    

db.documents.find({ 'versions.0.content.fwtweaeeba' : {$exists : true}}).forEach( function(obj) { 
        obj.versions[0].content.fwtweaeeba = parseFloat( obj.versions[0].content.fwtweaeeba ); 
        db.documents.save(obj); } );

db.documents.find({ 'versions.1.content.fwtweaeeba' : {$exists : true}}).forEach( function(obj) { 
        obj.versions[1].content.fwtweaeeba = parseFloat( obj.versions[1].content.fwtweaeeba );  
        db.documents.save(obj); } );

db.documents.find({ 'versions.2.content.fwtweaeeba' : {$exists : true}}).forEach( function(obj) { 
        obj.versions[2].content.fwtweaeeba = parseFloat( obj.versions[2].content.fwtweaeeba );  
        db.documents.save(obj); } );

এবং এটি পিএইচপি তে)))

foreach($db->documents->find(array("type" => "chair")) as $document){
    $db->documents->update(
        array('_id' => $document[_id]),
        array(
            '$set' => array(
                'versions.0.content.axdducvoxb' => (float)$document['versions'][0]['content']['axdducvoxb'],
                'versions.1.content.axdducvoxb' => (float)$document['versions'][1]['content']['axdducvoxb'],
                'versions.2.content.axdducvoxb' => (float)$document['versions'][2]['content']['axdducvoxb'],
                'axdducvoxb' => (float)$document['axdducvoxb']
            )
        ),
        array('$multi' => true)
    );


}

0

আমার ক্ষেত্রে, আমি নিম্নলিখিত ব্যবহার করি

function updateToSting(){
  var collection = "<COLLECTION-NAME>";
  db.collection(collection).find().forEach(function(obj) {
    db.collection(collection).updateOne({YOUR_CONDITIONAL_FIELD:obj.YOUR_CONDITIONAL_FIELD},{$set:{YOUR_FIELD:""+obj.YOUR_FIELD}});
  });
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.