2012-02-29 6 views
46

मान लें कि मेरे पास कुछ दस्तावेज़ों के साथ संग्रह है। कुछ इस तरह।एक मोंगोडीबी संग्रह में सभी डुप्लिकेट दस्तावेज़ों को एक प्रमुख फ़ील्ड

{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":1, "name" : "foo"} 
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":2, "name" : "bar"} 
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":3, "name" : "baz"} 
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":4, "name" : "foo"} 
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":5, "name" : "bar"} 
{ "_id" : ObjectId("4f127fa55e7242718200002d"), "id":6, "name" : "bar"} 

मैं इस संग्रह में "नाम" फ़ील्ड द्वारा सभी डुप्लीकेट प्रविष्टियों को ढूंढना चाहता हूं। जैसे "foo" दो बार प्रकट होता है और "बार" 3 बार प्रकट होता है।

+0

[इस समाधान] (http: // stackoverflow।कॉम/ए/33364353/1045444) –

उत्तर

16

नोट: यह समाधान समझने में सबसे आसान है, लेकिन सबसे अच्छा नहीं है।

आप पता लगाने के लिए कितनी बार एक दस्तावेज एक निश्चित क्षेत्र में शामिल है mapReduce उपयोग कर सकते हैं:

var map = function(){ 
    if(this.name) { 
     emit(this.name, 1); 
    } 
} 

var reduce = function(key, values){ 
    return Array.sum(values); 
} 

var res = db.collection.mapReduce(map, reduce, {out:{ inline : 1}}); 
db[res.result].find({value: {$gt: 1}}).sort({value: -1}); 
5

एक सामान्य मोंगो समाधान के लिए, MongoDB cookbook recipe for finding duplicates using group देखते हैं। ध्यान दें कि एकत्रीकरण तेज और अधिक शक्तिशाली है जिसमें यह डुप्लिकेट रिकॉर्ड के _id एस वापस कर सकता है।

के लिए, स्वीकृत उत्तर (MapReduce का उपयोग करके) वह कुशल नहीं है। इसके बजाय, हम group विधि का उपयोग कर सकते हैं:

$connection = 'mongodb://localhost:27017'; 
$con  = new Mongo($connection); // mongo db connection 

$db   = $con->test; // database 
$collection = $db->prb; // table 

$keys  = array("name" => 1); Select name field, group by it 

// set intial values 
$initial = array("count" => 0); 

// JavaScript function to perform 
$reduce  = "function (obj, prev) { prev.count++; }"; 

$g   = $collection->group($keys, $initial, $reduce); 

echo "<pre>"; 
print_r($g); 

आउटपुट यह होगा:

Array 
(
    [retval] => Array 
     (
      [0] => Array 
       (
        [name] => 
        [count] => 1 
       ) 

      [1] => Array 
       (
        [name] => MongoDB 
        [count] => 2 
       ) 

     ) 

    [count] => 3 
    [keys] => 2 
    [ok] => 1 
) 

बराबर SQL क्वेरी होगा: SELECT name, COUNT(name) FROM prb GROUP BY name। ध्यान दें कि हमें अभी भी सरणी से 0 की गिनती के साथ तत्वों को फ़िल्टर करने की आवश्यकता है। फिर, group का उपयोग कर कैननिकल समाधान के लिए MongoDB cookbook recipe for finding duplicates using group देखें।

+0

मोंगोडीबी कुकबुक का लिंक अप्रचलित है और 404 लौटाता है। – udachny

131

स्वीकार्य उत्तर बड़े संग्रहों पर बहुत धीमा है, और डुप्लिकेट रिकॉर्ड के _id एस वापस नहीं करता है।

एकत्रीकरण तेज हो गया है और _id रों लौट सकते हैं:

db.collection.aggregate([ 
    { $group: { 
    _id: { name: "$name" }, // replace `name` here twice 
    uniqueIds: { $addToSet: "$_id" }, 
    count: { $sum: 1 } 
    } }, 
    { $match: { 
    count: { $gte: 2 } 
    } }, 
    { $sort : { count : -1} }, 
    { $limit : 10 } 
]); 

एकत्रीकरण पाइप लाइन के पहले चरण में, $group ऑपरेटर uniqueIds से प्रत्येक _id मूल्य में name क्षेत्र द्वारा दस्तावेजों और दुकानों को एकत्रित करती समूहबद्ध रिकॉर्ड $sum ऑपरेटर इसे पास किए गए फ़ील्ड के मान जोड़ता है, इस मामले में स्थिर 1 - इस प्रकार count फ़ील्ड में समूहबद्ध रिकॉर्ड्स की संख्या को गिनती है।

पाइपलाइन के दूसरे चरण में, हम $match का उपयोग कम से कम 2, यानी डुप्लिकेट के count के साथ दस्तावेज़ फ़िल्टर करने के लिए करते हैं।

फिर, हम सबसे लगातार डुप्लिकेट पहले सॉर्ट, और इस क्वेरी शीर्ष 10

लिए परिणामों को सीमित कर नकली नाम के साथ $limit रिकॉर्ड, उनके _id रों के साथ अप करने के लिए उत्पादन होगा।

{ 
    "_id" : { 
    "name" : "Toothpick" 
}, 
    "uniqueIds" : [ 
    "xzuzJd2qatfJCSvkN", 
    "9bpewBsKbrGBQexv4", 
    "fi3Gscg9M64BQdArv", 
    ], 
    "count" : 3 
}, 
{ 
    "_id" : { 
    "name" : "Broom" 
    }, 
    "uniqueIds" : [ 
    "3vwny3YEj2qBsmmhA", 
    "gJeWGcuX6Wk69oFYD" 
    ], 
    "count" : 2 
} 
+0

डुप्लिकेट को हटाने के लिए आप [इस समाधान] का उपयोग कर सकते हैं (http://stackoverflow.com/a/33364353/1045444) –

+0

अब कैसे कर सकते हैं मैं इसे सी # का उपयोग कर बुलाता हूँ? – blueprintChris

+0

क्या यह समाधान कुंजी पर मौजूदा इंडेक्स का उपयोग करता है? मेरी चिंता यह बहुत बड़े संग्रह के खिलाफ चल रही है, जहां समूहित दस्तावेज स्मृति में फिट नहीं हो सकते हैं। – Iravanchi

संबंधित मुद्दे