Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从MongoDB中删除重复项_Mongodb_Mapreduce_Mongodb Query_Aggregation Framework - Fatal编程技术网

从MongoDB中删除重复项

从MongoDB中删除重复项,mongodb,mapreduce,mongodb-query,aggregation-framework,Mongodb,Mapreduce,Mongodb Query,Aggregation Framework,您好,我在mongodb(复制)中有约500万个文档,每个文档43个字段。如何删除重复文档。我试着 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 ,

您好,我在mongodb(复制)中有约500万个文档,每个文档43个字段。如何删除重复文档。我试着

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
}
如何解决这个问题?

从MongoDB 2.6和开始,用于创建索引的“dropDups”语法已被“弃用”。在大多数情况下,使用这种语法不是一个好主意,因为“删除”是任意的,任何“重复”都可以删除。这意味着“删除”的内容可能不是您真正想要删除的内容

无论如何,您遇到了一个“索引长度”错误,因为这里的索引键的值会比允许的更长。一般来说,在任何正常应用程序中,您都不“打算”索引43个字段

如果要从集合中删除“重复项”,则最好运行聚合查询以确定哪些文档包含“重复”数据,然后在该列表中循环删除已存在的“唯一项”中的“除一项外的所有项”“
\u id
来自目标集合的值。这可以通过操作实现最高效率

注意:我很难相信您的文档实际上包含43个“唯一”字段。“您所需要的”很可能只是简单地识别使文档“唯一”的那些字段,然后按照下面概述的流程进行操作:

var bulk=db.testkdd.initializeOrderedBulkOp(),
计数=0;
//在`\u id中列出使文档“唯一”的“所有”字段`
//我只是列举了一些例子,以供参考
db.testkdd.aggregate([
{“$组”:{
“_id”:{
“持续时间”:“$duration”,
“协议类型”:“$协议类型”,
“服务”:“$service”,
“flag”:“$flag”
},
“id”:{“$push”:“$\u id”},
“计数”:{“$sum”:1}
}},
{“$match”:{“count”:{“$gt”:1}}
],{“allowDiskUse”:true}).forEach(函数(doc){
doc.ids.shift();//删除第一个匹配项
bulk.find({“_id”:{“$in”:doc.ids}}).remove();//删除列表中的所有$
计数++;
//执行千分之一并重新初始化
如果(计数%1000==0){
bulk.execute();
bulk=db.testkdd.initializeOrderedBulkOp();
}
});
如果(计数%1000!=0)
bulk.execute();
如果您的MongoDB版本“低于”2.6,并且没有批量操作,那么您也可以尝试使用标准内部循环。还要注意的是,
.aggregate()
不会在此处返回光标,循环必须更改为:

db.testkdd.aggregate([
//管道如上所述
]).result.forEach(函数(文档){
doc.ids.shift();
remove({“_id”:{“$in”:doc.ids});
});

但一定要仔细查看您的文档,并且只包含“仅”您希望成为分组
\u id
一部分的“唯一”字段。否则,您将无法删除任何内容,因为其中没有重复项。

@mohamedzajith错误实际上是在告诉您该怎么做。将“allowDiskUse”添加到管道中。这是用聚合方法记录的。我还建议你“仍然”传递更多的字段,而不是那些真正构成“独特”组合的字段。如何在mongo中添加allowDiskUseshell@mohamedzajith对于聚合选项,在中有明确的示例。它们在管道参数数组之后指定。上面包括的例子。