我创建了一个mongodb,并且错误地以大写和小写字母的形式输入了重复值。
我使索引与众不同。 MongoDB区分大小写,因此将大写字母和小写字母视为不同的值。
现在我的问题是数据库已经有大约32 GB。我遇到了这个问题。请帮助我。
以下是样本:
db.tt.createIndex({'email':1},{unique:true})
> db.tt.find().pretty()
{
"_id" : ObjectId("591d706c0ef9acde11d7af66"),
"email" : "g@gmail.com",
"src" : [
{
"acc" : "ln"
},
{
"acc" : "drb"
}
]
}
{
"_id" : ObjectId("591d70740ef9acde11d7af68"),
"email" : "G@gmail.com",
"src" : [
{
"acc" : "ln"
},
{
"acc" : "drb"
},
{
"acc" : "dd"
}
]
}
如何将email
设为小写并将src值分配给原始值。请帮助我。
答案 0 :(得分:2)
您可以使用 .onclick
聚合运算符来实现此目的:
document.getElementById("boton").onclick = mostraralerta;
$toLower
允许保持 db.tt.aggregate([
{
$project:{
email:{
$toLower:"$email"
},
src:1
}
},
{
$unwind:"$src"
},
{
$group:{
_id:"$email",
src:{
$addToSet:"$src"
}
}
},
{
$project:{
_id:0,
email:"$_id",
src:1
}
},
{
$out:"anotherCollection"
}
])
个项目的明显出现
这会将此文档写入名为$addToSet
的新集合:
src
请注意,使用 anotherCollection
,您可以直接验证您的{ "email" : "g@gmail.com", "src" : [ { "acc" : "dd" }, { "acc" : "drb" }, { "acc" : "ln" } ] }
集合,但在此之前请务必了解您的操作,因为之前的所有数据都将丢失< / p>
答案 1 :(得分:0)
我能想到合并数据的最有效方法是运行聚合并循环结果以在批量操作中写回集合:
var ops = [];
db.tt.aggregate([
{ "$unwind": "$src" },
{ "$group": {
"_id": { "$toLower": "$email" },
"src": { "$addToSet": "$src" },
"ids": { "$addToSet": "$_id" }
}}
]).forEach(doc => {
var id = doc.ids.shift();
ops = [
...ops,
{
"deleteMany": {
"filter": { "_id": { "$in": doc.ids } }
}
},
{
"updateOne": {
"filter": { "_id": id },
"update": {
"$set": { "email": doc._id },
"$addToSet": { "src": { "$each": doc.src } }
}
}
},
];
if ( ops.length >= 500 ) {
db.tt.bulkWrite(ops);
ops = [];
}
});
if ( ops.length > 0 )
db.tt.bulkWrite(ops);
在步骤中,$unwind
数组项目可以通过$addToSet
在$group
下使用$toLower
email
进行合并价值。您还希望保留一组唯一的源文档ID。
在循环中,您shift
_id
doc.ids
的{{1}}值,并使用小写电子邮件和修订后的&#34; src&#34;更新该文档。组。在此处使用$addToSet
可使操作在文档可能发生的任何其他更新时保持安全。
然后循环中的其他操作将删除共享相同转换的案例电子邮件的其他文档,因此没有重复项。实际上先做那个。默认&#34;有序&#34;操作确保这很好。
并且在shell中执行,因为它是一次性操作,并且实际上就像显示的那样简单。