我正在尝试合并两个字段 这是我的收藏
db.Acc_Details.findOne()
{
"_id": ObjectId("577f43fe748646cc91370713"),
"Acc_Id": 1,
"Name": "xxxxx",
"Phone": NumberLong("123456789"),
"Email": "xxxxxx@gmail.com"
}
现在,我想将Phone
和Email
合并到contact
并更新此集合
db.Acc_Details.findOne()
{
"_id": ObjectId("577f43fe748646cc91370713"),
"Acc_Id": 1,
"Name": "xxxxx",
"Contact": {
"Phone": NumberLong("123456789"),
"Email": "xxxxxx@gmail.com"
}
}
这是我尝试的但我不知道它是否正确:
db.Acc_Details.aggregate([
{
$project: {
"Contact": {
"$map": {
input: { $literal: ["p1", "p2"] },
as: "p",
in: {
$cond: [
{ $eq: ["$$p", "p1"] },
"$Phone",
"$Email"
]
}
}
}
}
},
{ $unwind: "$Contact" }
])
结果是
{ "_id" : ObjectId("577f43fe748646cc91370713"), "Contact" : NumberLong("12356789") }
{ "_id" : ObjectId("577f43fe748646cc91370713"), "Contact" : "xxxxxx@gmail.com" }
有人可以帮我这个吗?
答案 0 :(得分:2)
这有点矫枉过正。下面是一个更简单的管道:
db.Acc_Details.aggregate([
{
"$project": {
"Acc_Id": 1,
"Name": 1,
"Contact": {
"Phone": "$Phone",
"Email": "$Email"
}
}
}
])
要使用新架构更新表,您需要利用bulkWrite()
API利用更新,这对于任务更有效。考虑以下批量更新操作,您只需使用 find()
光标进行迭代,并将字段更新为:
var ops = [];
db.Acc_Details.find().snapshot().forEach(function(doc) {
ops.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": {
"$set": {
"Contact": { "Phone": doc.Phone, "Email": doc.Email }
},
"$unset": { "Phone": "", "Email": "" }
}
}
});
if (ops.length === 500) {
db.Acc_Details.bulkWrite(ops);
ops = [];
}
})
if (ops.length > 0) db.Acc_Details.bulkWrite(ops);
或使用上述汇总结果:
var ops = [];
db.Acc_Details.aggregate([
{
"$project": {
"Contact": {
"Phone": "$Phone",
"Email": "$Email"
}
}
}
]).forEach(function(doc) {
ops.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": {
"$set": { "Contact": doc.Contact },
"$unset": { "Phone": "", "Email": "" }
}
}
});
if (ops.length === 500) {
db.Acc_Details.bulkWrite(ops);
ops = [];
}
})
if (ops.length > 0) db.Acc_Details.bulkWrite(ops);
或者对于MongoDB 2.6.x和3.0.x版本,请使用此版本的 Bulk
操作:
var bulk = db.Acc_Details.initializeUnorderedBulkOp(),
counter = 0;
db.Acc_Details.find().snapshot().forEach(function(doc) {
bulk.find({ "_id": doc._id }).updateOne({
"$set": {
"Contact": { "Phone": doc.Phone, "Email": doc.Email }
},
"$unset": { "Phone": "", "Email": "" }
});
if (counter % 500 === 0) {
bulk.execute();
bulk = db.Acc_Details.initializeUnorderedBulkOp();
}
});
if (counter % 1000 !== 0 ) bulk.execute();
这两种情况下的批量操作API都有助于减少服务器上的IO负载,方法是在集合中每500个文档中只发送一次请求进行处理。