Mongodb将多个对象转换为数组,就地,永久 [英] Mongodb convert multiple objects to an array, in place, permanently
问题描述
我有一个包含这种形式的文档的集合:
I have a collection with documents in this form:
{
"name" : "John Smith",
"store_affiliation" : {
"stores" : {
"ABCD" : {
"role" : "General Manager",
"startdate" : ISODate("1970-01-01T00:00:00.000+0000"),
"enddate" : ISODate("1980-01-01T00:00:00.000+0000"),
"permissions" : "GM"
},
"1234" : {
"role" : "Owner",
"startdate" : ISODate("1970-01-01T00:00:00.000+0000"),
"enddate" : null,
"permissions" : "ALL"
},
"4321" : {
"role" : "Owner",
"startdate" : ISODate("1990-01-01T00:00:00.000+0000"),
"enddate" : null,
"permissions" : "ALL"
}
}
}
...但我需要商店列表采用这种形式(商店"数组):
...but I need the list of stores to be in this form (an array of "stores"):
{ "name" : "John Smith",
"store_affiliation" : {
"stores" : [
{
"store_code" : "ABCD",
"role" : "General Manager",
"startdate" : ISODate("1970-01-01T00:00:00.000+0000"),
"enddate" : ISODate("1980-01-01T00:00:00.000+0000"),
"permissions" : "GM"
},
{
"store_code" : "1234",
"role" : "Owner",
"startdate" : ISODate("1970-01-01T00:00:00.000+0000"),
"enddate" : null,
"permissions" : "ALL"
},
{
"shop_id" : "4321",
"role" : "Owner",
"startdate" : ISODate("1990-01-01T00:00:00.000+0000"),
"enddate" : null,
"permissions" : "ALL"
}
]
}
我研究过在 aggregate
管道中使用 $project
、$group
和 $push
,但我感觉使用 aggregate
甚至可能是死路一条,因为我不是在查询结果;我正在尝试永久修改集合中的每个文档(数千个).
I have researched using $project
, $group
and $push
in an aggregate
pipeline, but I feel like using aggregate
may even be a dead end, because I'm not after a query result; I'm trying to modify every document (thousands) in the collection permanently.
推荐答案
您可以在 3.4
版本中尝试以下聚合管道.
You can try below aggregation pipeline in 3.4
version.
下面的聚合使用 stores 嵌入文档更改为键值对数组rel="nofollow noreferrer">$objectToArray
后跟 $map
输出带有新字段的转换数组,同时保留所有现有字段.
Below aggregation changes the stores
embedded document into array of key value pairs using $objectToArray
followed by $map
to output transformed array of with new field while keeping all the existing fields.
批量更新以编写新的商店结构.
Bulk update to write the new stores structure.
var bulk = db.getCollection(col).initializeUnorderedBulkOp();
var count = 0;
var batch = 1;
db.getCollection(col).aggregate([
{"$match":{"store_affiliation.stores":{"$ne":{"$type":4}}}},
{"$addFields":{
"stores":{
"$map":{
"input":{"$objectToArray": "$store_affiliation.stores"},
"in":{
"store_code":"$$this.k",
"role":"$$this.v.role",
"startdate":"$$this.v.startdate",
"enddate":"$$this.v.enddate",
"permissions":"$$this.v.permissions"
}
}
}
}}]).forEach(function(doc){
var _id = doc._id;
var stores = doc.stores;
bulk.find({ "_id" : _id }).updateOne(
{ $set: {"store_affiliation.stores" : stores} }
);
count++;
if (count == batch) {
bulk.execute();
bulk = db.getCollection(col).initializeUnorderedBulkOp();
count = 0;
}
});
if (count > 0) {
bulk.execute();
}
这篇关于Mongodb将多个对象转换为数组,就地,永久的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!