2016-02-29 7 views
6

में डुप्लिकेट निकालें मेरे पास "contact_id" नामक फ़ील्ड वाला संग्रह है। मेरे संग्रह में मेरे पास इस कुंजी के साथ डुप्लिकेट रजिस्ट्रार हैं।MongoDB

मैं डुप्लिकेट कैसे हटा सकता हूं, जिसके परिणामस्वरूप केवल एक रजिस्टर हो सकता है?

मैं पहले से ही करने की कोशिश की:

db.PersonDuplicate.ensureIndex({"contact_id": 1}, {unique: true, dropDups: true}) 

लेकिन काम नहीं किया, क्योंकि समारोह dropDups नहीं रह गया है MongoDB 3.x में उपलब्ध है

मैं उपयोग कर रहा हूँ 3.2

धन्यवाद

उत्तर

18

हां, ड्रॉपडप्स अच्छे के लिए चला गया है। लेकिन आप निश्चित रूप से थोड़ा सा प्रयास करके अपना लक्ष्य प्राप्त कर सकते हैं।

आपको पहले सभी डुप्लिकेट पंक्तियों को ढूंढने की आवश्यकता है और फिर पहले को छोड़कर सभी को हटा दें।

db.dups.aggregate([{$group:{_id:"$contact_id", dups:{$push:"$_id"}, count: {$sum: 1}}}, 
{$match:{count: {$gt: 1}}} 
]).forEach(function(doc){ 
    doc.dups.shift(); 
    db.dups.remove({_id : {$in: doc.dups}}); 
}); 

जैसा कि आप देख doc.dups.shift() सरणी से _ id पहले निकालें और फिर dups सरणी में _ids शेष के साथ सभी दस्तावेजों को हटा देगा।

उपरोक्त स्क्रिप्ट सभी डुप्लिकेट दस्तावेज़ों को हटा देगा।

+0

मैं कोशिश करते हैं और अगर काम टिप्पणी करना आरंभ कर देंगे! धन्यवाद – Jhonathan

+0

अच्छा लगता है। मुझे बताएं कि यह कैसे जाता है। – Saleem

+0

हाय। आंशिक काम किया। जब मैं एक छोटा संग्रह डालता हूं तो ठीक काम करता है। लेकिन जब मैं एक बड़े संग्रह में निष्पादित करता हूं तो डेटाबेस "लॉक" और अन्य क्वेरी टाइमआउट पर जाती है। – Jhonathan

0

शायद यह एक tmpColection बनाने, अद्वितीय अनुक्रमणिका बनाने, फिर स्रोत से डेटा कॉपी करने का एक अच्छा प्रयास हो सकता है, और अंतिम चरण स्वैप नाम होंगे?

अन्य विचार, मैं था सही पर सेट किया justOne पैरामीटर के साथ निकालें() विधि या 1.

var itemsToDelete = db.PersonDuplicate.aggregate([ 
{$group: { _id:"$_id", count:{$sum:1}}}, 
{$match: {count: {$gt:1}}}, 
{$group: { _id:1, ids:{$addToSet:"$_id"}}} 
]) 

और एक बनाने बुला के माध्यम से दोगुनी सरणी (एकत्रीकरण का प्रयोग करके) और फिर पाश में अनुक्रमित पाने के लिए है ids सरणी के माध्यम से लूप आपके लिए यह समझ बनाता है?

5

यह मोंगोड 3+ के लिए एक अच्छा पैटर्न है जो यह भी सुनिश्चित करता है कि आप हमारी स्मृति को नहीं चलाएंगे जो वास्तव में बड़े संग्रह के साथ हो सकता है। आप एक dedup.js फ़ाइल को यह बचा सकता है इसे अनुकूलित, और के साथ अपने वांछित डेटाबेस के खिलाफ इसे चलाने: मोंगो स्थानीय होस्ट: 27017/YOURDB dedup.js

var duplicates = []; 

db.runCommand(
    {aggregate: "YOURCOLLECTION", 
    pipeline: [ 
     { $group: { _id: { DUPEFIELD: "$DUPEFIELD"}, dups: { "$addToSet": "$_id" }, count: { "$sum": 1 } }}, 
     { $match: { count: { "$gt": 1 }}} 
    ], 
    allowDiskUse: true } 
) 
.result 
.forEach(function(doc) { 
    doc.dups.shift(); 
    doc.dups.forEach(function(dupId){ duplicates.push(dupId); }) 
}) 
printjson(duplicates); //optional print the list of duplicates to be removed 

db.YOURCOLLECTION.remove({_id:{$in:duplicates}});