डिफ़ॉल्ट रूप से सभी "नंबर" को मोंगोडीबी में "डबल" के रूप में संग्रहीत किया जाता है जब तक कि आम तौर पर ओवरवाइज नहीं डाला जाता है।
निम्नलिखित नमूने लें:
db.sample.insert({ "a": 1 })
db.sample.insert({ "a": NumberLong(1) })
db.sample.insert({ "a": NumberInt(1) })
db.sample.insert({ "a": 1.223 })
यह इस तरह का संग्रह देता है:
{ "_id" : ObjectId("559bb1b4a23c8a3da73e0f76"), "a" : 1 }
{ "_id" : ObjectId("559bb1bba23c8a3da73e0f77"), "a" : NumberLong(1) }
{ "_id" : ObjectId("559bb29aa23c8a3da73e0f79"), "a" : 1 }
{ "_id" : ObjectId("559bb30fa23c8a3da73e0f7a"), "a" : 1.223 }
विभिन्न कंस्ट्रक्टर कार्यों के बावजूद ध्यान दें कि कितने डेटा बिंदु समान दिखते हैं। MongoDB शेल हमेशा उनके बीच स्पष्ट रूप से अंतर नहीं करता है, लेकिन एक तरीका है जिससे आप बता सकते हैं।
निश्चित रूप से $type
. है क्वेरी ऑपरेटर, जो बीएसओएन प्रकारों के चयन की अनुमति देता है।
तो टाइप 1 के साथ इसका परीक्षण करें - जो "डबल" है:
> db.sample.find({ "a": { "$type": 1 } })
{ "_id" : ObjectId("559bb1b4a23c8a3da73e0f76"), "a" : 1 }
{ "_id" : ObjectId("559bb30fa23c8a3da73e0f7a"), "a" : 1.223 }
आप देखते हैं कि पहली प्रविष्टि और अंतिम दोनों का चयन किया गया है, लेकिन निश्चित रूप से अन्य दो नहीं।
तो अब BSON टाइप 16 के लिए परीक्षण करें - जो कि एक 32-बिट पूर्णांक है
> db.sample.find({ "a": { "$type": 16 } })
{ "_id" : ObjectId("559bb29aa23c8a3da73e0f79"), "a" : 1 }
वह "तीसरा" इंसर्शन था जिसमें NumberInt()
. का इस्तेमाल किया गया था खोल में कार्य करता है। ताकि आपके ड्राइवर से फ़ंक्शन और अन्य क्रमांकन इस विशिष्ट बीएसओएन प्रकार को सेट कर सकें।
और बीएसओएन टाइप 18 के लिए - जो 64-बिट पूर्णांक है
> db.sample.find({ "a": { "$type": 18 } })
{ "_id" : ObjectId("559bb1bba23c8a3da73e0f77"), "a" : NumberLong(1) }
"दूसरा" सम्मिलन जो NumberLong()
. के माध्यम से तैयार किया गया था ।
यदि आप उन चीजों को "बाहर निकालना" चाहते हैं जो "दोहरी नहीं" थीं तो आप ऐसा करेंगे:
db.sample.find({ "$or": [{ "a": { "$type": 16 } },{ "a": { "$type": 18 } }]})
"डबल" के अलावा केवल अन्य मान्य संख्यात्मक प्रकार कौन से हैं।
तो अपने संग्रह में इन्हें "रूपांतरित" करने के लिए, आप इस तरह "बल्क" प्रक्रिया कर सकते हैं:
var bulk = db.sample.initializeUnorderedBulkOp(),
count = 0;
db.sample.find({
"$or": [
{ "a": { "$type": 16 } },
{ "a": { "$type": 18 } }
]
}).forEach(function(doc) {
bulk.find({ "_id": doc._id })
.updateOne({
"$set": { "b": doc.a.valueOf() } ,
"$unset": { "a": 1 }
});
bulk.find({ "_id": doc._id })
.updateOne({ "$rename": { "b": "a" } });
count++;
if ( count % 1000 == 0 ) {
bulk.execute()
bulk = db.sample.initializeUnOrderedBulkOp();
}
})
if ( count % 1000 != 0 ) bulk.execute();
जो करता है वह तीन चरणों में "थोक में" किया जाता है:
- किसी नए फ़ील्ड में "डबल" के रूप में मान को फिर से कास्ट करें
- अवांछित प्रकार के साथ पुराने फ़ील्ड को हटा दें
- नई फ़ील्ड का नाम बदलकर पुराने फ़ील्ड के नाम पर रखें
यह आवश्यक है चूंकि बीएसओएन प्रकार की जानकारी एक बार बनाई गई फ़ील्ड तत्व के लिए "चिपचिपा" है। इसलिए "री-कास्ट" करने के लिए आपको पुराने डेटा को पूरी तरह से हटाना होगा जिसमें मूल फ़ील्ड असाइनमेंट शामिल है।
ताकि यह समझा जाए कि आपके दस्तावेज़ों में अवांछित प्रकारों का "पता लगाना" और "पुनः-कास्ट" कैसे किया जाए।