更新 MongoDB 中的嵌套数组
Update nested array in MongoDB
我正在尝试在 mongo shell 中进行更新,但遇到了问题。
我有以下 json:
{
"_id" : ObjectId("56cc03c16f4e85f538ef79ae"),
"contact_id" : NumberLong(1000295524418),
"gender" : 1,
"phonetic_gender" : 1,
"first_name" : "LEANDRO",
"score" : 44,
"address" : [
{
"address_id" : NumberLong(2634224807),
"rank" : 201604.0,
"score" : 7.0,
"street_type" : "AV",
"street_title" : "DA",
"street" : "EMILIA DE CASTRO MARTINS",
"number" : 34.0,
"district" : "JARDIM BELA VISTA",
"city" : "GUARULHOS",
"state" : "SP",
"zip_code" : 7132470.0,
"create_date" : ISODate("2014-08-07T00:00:00.000Z"),
"update_date" : ISODate("2016-05-03T00:00:00.000Z")
},
{
"address_id" : NumberLong(2634735566),
"rank" : 201410,
"score" : 10,
"street_type" : "AV",
"street_title" : "DA",
"street" : "EMILIA DE CASTRO MARTINS",
"district" : "JARDIM BELA VISTA",
"city" : "GUARULHOS",
"state" : "SP",
"zip_code" : "07132470",
"create_date" : ISODate("2014-08-07T03:00:00.000Z"),
"update_date" : ISODate("2014-08-07T03:00:00.000Z")
}
]}
我需要检查所有文档并更新地址数组中字段 "rank" 和 "score" 的类型。
查看我正在执行的以下代码:
var total = 0
var skip = 0
var total_adress = db.company.count() - skip
var bulk = db.person.initializeUnorderedBulkOp()
var person = db.getCollection('Person').find( {$and:[ {"contact_id":1000295524418}).addOption(DBQuery.Option.noTimeout).forEach(
function(person){
var contact_id = person.contact_id.valueOf()
bulk.find(
{ contact_id: contact_id }
).update(
{
$set: {
"address.$.zip_code":"address.zip_code".toString(),
"address.$.rank": NumberInt("address.rank"),
"address.$.number": "address.number".toString(),
"address.$.score": NumberInt("address.score") - 2
}
}
);
if((++total % 1000) === 0){
print("Total person....: " + total_adress)
print("Iniciando bulk..: " + Date())
bulk.execute({ w: 0 })
bulk = db.company.initializeUnorderedBulkOp()
print("Fim bulk........: " + Date())
print("#############################################################################")
}
}); bulk.execute(); print(total);
现在问题来了,当我在Mongo运行这个命令的时候,它没有报错。确保它落在 foreach 内并正确搜索我的字段中的数据,问题只是更新不起作用。
谢谢!
个人文档中的地址键是一个文档数组。根据 jstell 的评论,解决方案之一是执行以下步骤:
- 将地址数组复制到
array_of_addresses
变量中。
- 遍历
array_of_addresses
的每个文档并根据需要更新密钥。
- 在
bulk.find.update
管道中,使用新更新的数组 array_of_addresses
更新 address
键值。
请注意,在 find() 和执行批量更新之间对地址数组的任何更新都可能被覆盖。
还建议了其他小改动:
getCollection('person')
而不是 getCollection('Person')
查找命令中缺少 square/curly 括号:find( {$and:[{"contact_id":1000295524418} ]} )
var total = 0;
var skip = 0;
var bulk = db.person.initializeUnorderedBulkOp();
db.getCollection('person').find({$and:[{"contact_id"1000295524418}]}).addOption(DBQuery.Option.noTimeout).forEach(
function(person){
//extract the array into array_of_addresses variable
var contact_id = person.contact_id.valueOf();
var array_of_addresses = person.address.valueOf() ;
//Loop through the array_of_addresses
for ( var i = 0; i< array_of_addresses.length ; i++) {
//assign element of array to address variable
address = array_of_addresses[i];
//DO YOUR MODIFICATIONS HERE. e.g. zipcode
zip_code = address.zip_code.valueOf().toString();
address.zip_code = zip_code;
}
//Set the modified array value to address element of the document
bulk.find(
{ contact_id: contact_id }
).update(
{
$set: {
address : array_of_addresses
}
}
);
});
//bulk execute
bulk.execute();
我正在尝试在 mongo shell 中进行更新,但遇到了问题。
我有以下 json:
{
"_id" : ObjectId("56cc03c16f4e85f538ef79ae"),
"contact_id" : NumberLong(1000295524418),
"gender" : 1,
"phonetic_gender" : 1,
"first_name" : "LEANDRO",
"score" : 44,
"address" : [
{
"address_id" : NumberLong(2634224807),
"rank" : 201604.0,
"score" : 7.0,
"street_type" : "AV",
"street_title" : "DA",
"street" : "EMILIA DE CASTRO MARTINS",
"number" : 34.0,
"district" : "JARDIM BELA VISTA",
"city" : "GUARULHOS",
"state" : "SP",
"zip_code" : 7132470.0,
"create_date" : ISODate("2014-08-07T00:00:00.000Z"),
"update_date" : ISODate("2016-05-03T00:00:00.000Z")
},
{
"address_id" : NumberLong(2634735566),
"rank" : 201410,
"score" : 10,
"street_type" : "AV",
"street_title" : "DA",
"street" : "EMILIA DE CASTRO MARTINS",
"district" : "JARDIM BELA VISTA",
"city" : "GUARULHOS",
"state" : "SP",
"zip_code" : "07132470",
"create_date" : ISODate("2014-08-07T03:00:00.000Z"),
"update_date" : ISODate("2014-08-07T03:00:00.000Z")
}
]}
我需要检查所有文档并更新地址数组中字段 "rank" 和 "score" 的类型。
查看我正在执行的以下代码:
var total = 0
var skip = 0
var total_adress = db.company.count() - skip
var bulk = db.person.initializeUnorderedBulkOp()
var person = db.getCollection('Person').find( {$and:[ {"contact_id":1000295524418}).addOption(DBQuery.Option.noTimeout).forEach(
function(person){
var contact_id = person.contact_id.valueOf()
bulk.find(
{ contact_id: contact_id }
).update(
{
$set: {
"address.$.zip_code":"address.zip_code".toString(),
"address.$.rank": NumberInt("address.rank"),
"address.$.number": "address.number".toString(),
"address.$.score": NumberInt("address.score") - 2
}
}
);
if((++total % 1000) === 0){
print("Total person....: " + total_adress)
print("Iniciando bulk..: " + Date())
bulk.execute({ w: 0 })
bulk = db.company.initializeUnorderedBulkOp()
print("Fim bulk........: " + Date())
print("#############################################################################")
}
}); bulk.execute(); print(total);
现在问题来了,当我在Mongo运行这个命令的时候,它没有报错。确保它落在 foreach 内并正确搜索我的字段中的数据,问题只是更新不起作用。
谢谢!
个人文档中的地址键是一个文档数组。根据 jstell 的评论,解决方案之一是执行以下步骤:
- 将地址数组复制到
array_of_addresses
变量中。 - 遍历
array_of_addresses
的每个文档并根据需要更新密钥。 - 在
bulk.find.update
管道中,使用新更新的数组array_of_addresses
更新address
键值。
请注意,在 find() 和执行批量更新之间对地址数组的任何更新都可能被覆盖。
还建议了其他小改动:
getCollection('person')
而不是getCollection('Person')
查找命令中缺少 square/curly 括号:
find( {$and:[{"contact_id":1000295524418} ]} )
var total = 0; var skip = 0; var bulk = db.person.initializeUnorderedBulkOp(); db.getCollection('person').find({$and:[{"contact_id"1000295524418}]}).addOption(DBQuery.Option.noTimeout).forEach( function(person){ //extract the array into array_of_addresses variable var contact_id = person.contact_id.valueOf(); var array_of_addresses = person.address.valueOf() ; //Loop through the array_of_addresses for ( var i = 0; i< array_of_addresses.length ; i++) { //assign element of array to address variable address = array_of_addresses[i]; //DO YOUR MODIFICATIONS HERE. e.g. zipcode zip_code = address.zip_code.valueOf().toString(); address.zip_code = zip_code; } //Set the modified array value to address element of the document bulk.find( { contact_id: contact_id } ).update( { $set: { address : array_of_addresses } } ); }); //bulk execute bulk.execute();