Mongodb 将数组封装/转换为对象数组
我目前正在修改模式,需要使用聚合框架和 我希望能够获取此阵列:Mongodb 将数组封装/转换为对象数组,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我目前正在修改模式,需要使用聚合框架和 我希望能够获取此阵列: { ..., "images" : [ "http://example.com/...", "http://example.com/...", "http://example.com/..." ] } 并聚合到一个类似的数组中,在该数组中封装原始值: { ..., "images" : [ {url: "htt
{
...,
"images" : [
"http://example.com/...",
"http://example.com/...",
"http://example.com/..."
]
}
并聚合到一个类似的数组中,在该数组中封装原始值:
{
...,
"images" : [
{url: "http://example.com/..."},
{url: "http://example.com/..."},
{url: "http://example.com/..."}
]
}
这个慢的查询可以正常工作,但要解开整个集合,花费要高得离谱
[
{
$match: {}
},
{
$unwind: {
path : "$images",
}
},
{
$group: {
_id: "$_id",
images_2: {$addToSet: {url: "$images"}}
}
},
]
如何通过project
或其他更便宜的聚合实现这一点?expression应该完成这项工作,请尝试以下方法:
db.col.aggregate([
{
$project: {
images: {
$map: {
input: '$images',
as: 'url',
in: {
url: '$$url'
}
}
}
}
}
]);
您不需要为此使用
bulkWrite()
方法
可以使用聚合数组运算符将表达式应用于数组中的每个元素
这里,表达式只是创建一个新对象,其中值是数组中的项
let mapExpr = {
"$map": {
"input": "$images",
"as": "imageUrl",
"in": { "url": "$$imageUrl }
}
};
最后,您可以使用$out
聚合管道操作符覆盖集合或将结果写入其他集合
[
{
$match: {}
},
{
$unwind: {
path : "$images",
}
},
{
$group: {
_id: "$_id",
images_2: {$addToSet: {url: "$images"}}
}
},
]
当然,$map
不是聚合管道操作符,因此这意味着必须在管道阶段使用$map
表达式
这取决于您的MongoDB版本
最好的方法是在MongoDB 3.4中使用更改文档中“images”字段的值
db.collection.aggregate([
{ "$addFields": { "images": mapExpr }},
{ "$out": "collection }
])
从MongoDB 3.2向后看,您需要使用pipeline阶段,但也需要在文档中手动包含所有其他字段
db.collection.aggregate([
{ "$project": { "images": mapExpr } },
{ "$out": "collection }
])