복붙노트

[MONGODB] MongoDB의에서 중복 제거

MONGODB

MongoDB의에서 중복 제거

안녕하세요 저는 MongoDB를 (복제)에서 ~ 5 백만 문서 각 문서 (43 개) 필드가 있습니다. 어떻게 중복 문서를 제거합니다. 나는 tryed

db.testkdd.ensureIndex({
        duration  : 1 , protocol_type  : 1 , service  : 1 ,
        flag  : 1 , src_bytes  : 1 , dst_bytes  : 1 ,
        land  : 1 , wrong_fragment  : 1 , urgent  : 1 ,
        hot  : 1 , num_failed_logins  : 1 , logged_in  : 1 ,
        num_compromised  : 1 , root_shell  : 1 , su_attempted  : 1 ,
        num_root  : 1 , num_file_creations  : 1 , num_shells  : 1 ,
        num_access_files  : 1 , num_outbound_cmds  : 1 , is_host_login  : 1 ,
        is_guest_login  : 1 , count  : 1 ,  srv_count  : 1 ,
        serror_rate  : 1 , srv_serror_rate  : 1 , rerror_rate  : 1 ,
        srv_rerror_rate  : 1 , same_srv_rate  : 1 , diff_srv_rate  : 1 ,
        srv_diff_host_rate  : 1 , dst_host_count  : 1 , dst_host_srv_count  : 1 ,
        dst_host_same_srv_rate  : 1 , dst_host_diff_srv_rate  : 1 ,
        dst_host_same_src_port_rate  : 1 ,  dst_host_srv_diff_host_rate  : 1 ,
        dst_host_serror_rate  : 1 , dst_host_srv_serror_rate  : 1 ,
        dst_host_rerror_rate  : 1 , dst_host_srv_rerror_rate  : 1 , lable  : 1 
    },
    {unique: true, dropDups: true}
)

이 내가 오류 "에 errmsg"를 얻을 코드 실행 인덱스에서 생성 된 "네임 스페이스 이름을 ..

{
    "ok" : 0,
    "errmsg" : "namespace name generated from index name \"project.testkdd.$duration_1_protocol_type_1_service_1_flag_1_src_bytes_1_dst_bytes_1_land_1_wrong_fragment_1_urgent_1_hot_1_num_failed_logins_1_logged_in_1_num_compromised_1_root_shell_1_su_attempted_1_num_root_1_num_file_creations_1_num_shells_1_num_access_files_1_num_outbound_cmds_1_is_host_login_1_is_guest_login_1_count_1_srv_count_1_serror_rate_1_srv_serror_rate_1_rerror_rate_1_srv_rerror_rate_1_same_srv_rate_1_diff_srv_rate_1_srv_diff_host_rate_1_dst_host_count_1_dst_host_srv_count_1_dst_host_same_srv_rate_1_dst_host_diff_srv_rate_1_dst_host_same_src_port_rate_1_dst_host_srv_diff_host_rate_1_dst_host_serror_rate_1_dst_host_srv_serror_rate_1_dst_host_rerror_rate_1_dst_host_srv_rerror_rate_1_lable_1\" is too long (127 byte max)",
    "code" : 67
}

어떻게이 문제를 해결할 수 있습니까?

해결법

  1. ==============================

    1.인덱스 생성은 "dropDups"구문 MongoDB를 2.6으로 "중단"및 MongoDB를 3.0에서 제거되었다. 그것은 "제거"로 사용하는 대부분의 경우 아주 좋은 생각이 아니다 임의 및 제거 할 수있다 "중복". 어떤 "삭제"됩니다 무엇을 의미 당신이 정말로 제거 원하지 않는 결과를 얻을 수도 있습니다.

    인덱스 생성은 "dropDups"구문 MongoDB를 2.6으로 "중단"및 MongoDB를 3.0에서 제거되었다. 그것은 "제거"로 사용하는 대부분의 경우 아주 좋은 생각이 아니다 임의 및 제거 할 수있다 "중복". 어떤 "삭제"됩니다 무엇을 의미 당신이 정말로 제거 원하지 않는 결과를 얻을 수도 있습니다.

    어쨌든, 당신은 인덱스 키의 값 이후에 "인덱스 길이"오류로 실행하고 여기에 더 이상 허용되는 것입니다. 일반적으로 인덱스에있는 일반 응용 프로그램에서 43 개 필드를, 당신이 "의미"되지 않습니다 말하기.

    당신이 컬렉션에서 "중복"을 제거하려는 경우 가장 좋은 건 _id가 포함 된 이미 "독특한"의 "하나를 제외한 모든"을 제거하는 목록을 다음주기를 "복제"데이터와 어떤 문서를 결정하기 위해 집계 쿼리를 실행하는 것입니다 대상 컬렉션의 값. 이는 최대 효율을위한 "대량"작업을 수행 할 수 있습니다.

    참고 : 나는 당신의 문서가 실제로 43 "독특한"필드를 포함 믿기 어렵다를 찾을 수 있습니까. 그것은 아래에 설명 된대로 "모두 당신이 필요"단순히 문서 "독특한"할 만 필드를 식별 한 후 절차에 따라하는 것 같다 :

    var bulk = db.testkdd.initializeOrderedBulkOp(),
        count = 0;
    
    // List "all" fields that make a document "unique" in the `_id`
    // I am only listing some for example purposes to follow
    db.testkdd.aggregate([
        { "$group": {
            "_id": {
               "duration" : "$duration",
              "protocol_type": "$protocol_type", 
              "service": "$service",
              "flag": "$flag"
            },
            "ids": { "$push": "$_id" },
            "count": { "$sum": 1 }
        }},
        { "$match": { "count": { "$gt": 1 } } }
    ],{ "allowDiskUse": true}).forEach(function(doc) {
        doc.ids.shift();     // remove first match
        bulk.find({ "_id": { "$in": doc.ids } }).remove();  // removes all $in list
        count++;
    
        // Execute 1 in 1000 and re-init
        if ( count % 1000 == 0 ) {
           bulk.execute();
           bulk = db.testkdd.initializeOrderedBulkOp();
        }
    });
    
    if ( count % 1000 != 0 ) 
        bulk.execute();
    

    당신이 MongoDB의 버전이있는 경우 2.6보다 "낮은"다음 루프 내부 표준 .remove ()를 시도뿐만 아니라 수 있습니다 대량 작업이 없습니다. 또한 그 .aggregate () 여기에 커서를 반환하지 않습니다 및 루핑해야 변화에 주목 :

    db.testkdd.aggregate([
       // pipeline as above
    ]).result.forEach(function(doc) {
        doc.ids.shift();  
        db.testkdd.remove({ "_id": { "$in": doc.ids } });
    });
    

    그러나 밀접 만 포함 문서를보고 확인을 "그냥"당신이 기대하는 "독특한"필드는 그룹화 _id의 일부가 될 수 있습니다. 더 중복이 없기 때문에 그렇지 않으면 당신은 전혀 아무것도 제거하지 끝낸다.

  2. from https://stackoverflow.com/questions/31557053/remove-duplicates-from-mongodb by cc-by-sa and MIT license