gpt4 book ai didi

arrays - Mongodb - 将具有动态字段的 map 转换为数组

转载 作者:可可西里 更新时间:2023-11-01 10:02:50 26 4
gpt4 key购买 nike

我在 mongodb 中有以下结构:

db.coll1.findOne({}, {myMap:1}):

{
"x1-y1": {
x: x1,
y: y1,
etc: ..
},
"x2-y2": {..}
}

其中 x 和 y 在 0..100 范围内。

我认为使用动态命名的字段不是一个好主意,我想将此映射转换为数组:

db.coll1.findOne({}, {myArr:1}):

{[
{
x: x1,
y: y1,
etc: ..
},
{ .. }
]}

我不需要这些字段的索引。如何做到这一点?

最佳答案

使用 MongoDB 3.4.4 及更新版本:

$objectToArray 运算符在这种情况下效果很好,但要获得所需的结果,您需要将其用作 $map 的输入表达式 并将 myMap 字段替换为 $map 的结果 使用 $addFields .

以下面的例子为例:

填充测试集合:

db.test.insert({
"myMap": {
"0-1": {
"x": 0,
"y": 1
},
"1-2": {
"x": 1,
"y": 2
}
}
})

流水线

db.test.aggregate([
{ "$addFields": {
"myMap": {
"$map": {
"input": { "$objectToArray": "$myMap" },
"as": "el",
"in": "$$el.v"
}
}
} }
])

输出

{
"_id" : ObjectId("5ba75f206346675838fec680"),
"myMap" : [
{
"x" : 0.0,
"y" : 1.0
},
{
"x" : 1.0,
"y" : 2.0
}
]
}

对于不支持 $objectToArray 的旧 MongoDB 版本 运算符,总体思路是遍历集合,为每个文档将子文档键映射到一个新数组,并使用现在存储数组的字段更新文档。直觉最好用一个例子来解释,这假设你在集合中有一些文档:

更新

db.test.find({}).forEach(function(doc){    
var new_arr = Object.keys(doc.myMap).map(function(key){return doc.myMap[key]});
doc["myMap"] = new_arr;
db.test.save(doc);
})

查询

db.test.find()

示例输出

{
"_id" : ObjectId("57bdae6ce3f9ad02c421e448"),
"myMap" : [
{
"x" : 0,
"y" : 1
},
{
"x" : 1,
"y" : 2
}
]
}

对于更大的集合,最好利用 bulkWrite() 的更新 应用程序接口(interface):

var ops = [];
db.test.find({}).forEach(function(doc){
var new_arr = Object.keys(doc.myMap).map(function(key){return doc.myMap[key]});
ops.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": { "$set": { "myMap": new_arr } }
}
});
if (ops.length == 1000) {
db.test.bulkWrite(ops);
ops = [];
}
});

if (ops.length > 0) { db.test.bulkWrite(ops); }

如果您的 MongDB 版本不支持 bulkWrite API,请使用 Bulk() 2.6 和 3.0 版本可用的方法:

var bulk = db.test.initializeUnorderedBulkOp(),   
counter = 0;
db.test.find({}).forEach(function(doc) {
var new_arr = Object.keys(doc.myMap).map(function(key){return doc.myMap[key]});
bulk.find({ "_id": doc._id }).updateOne({
"$set": { "myMap": new_arr }
});
counter++;

if (counter % 1000 === 0) {
bulk.execute();
bulk = db.test.initializeUnorderedBulkOp();
}
});

if (counter % 1000 !== 0)
bulk.execute();

关于arrays - Mongodb - 将具有动态字段的 map 转换为数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39124981/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com