A.V*_*rno 5 ruby arrays mongodb
我的mongoDB文档中的一些字段如下所示:
{
...
Countries: [["Spain", "France"]]
...
}
Run Code Online (Sandbox Code Playgroud)
或这个:
{
...
Countries: [["Spain"],["Russia", "Egypt"]]
...
}
Run Code Online (Sandbox Code Playgroud)
我想做的就是[["Spain", "France"]]转入["Spain", "France"]和[["Spain"],["Russia", "Egypt"]]转换["Spain", "Russia", "Egypt"],类似于flatten在Ruby中使用方法.
有没有办法在mongoDB中展平数组?我需要在整个集合中的所有文档中展平数组,而不仅仅是单个文档,如果这很重要,数组中的值及其数量也会因文档而异.
我也使用Ruby作为mongo的驱动程序,因此使用Ruby驱动程序的方法对我也很有用.
Mat*_* Lo 11
在 Mongo 3.4+ 中,您可以使用$reduce扁平化二维数组。
db.collection.aggregate(
[
{
$project: {
"countries": {
$reduce: {
input: '$Countries',
initialValue: [],
in: {$concatArrays: ['$$value', '$$this']}
}
}
}
}
]
)
Run Code Online (Sandbox Code Playgroud)
文档:https : //docs.mongodb.com/manual/reference/operator/aggregation/reduce/
您需要使用两个展开阶段和一个小组阶段执行聚合操作。基本规则是放松次数与巢深度相同。这里嵌套的级别是 2,所以我们展开两次。
collection.aggregate([
{$unwind => "$Countries"},
{$unwind => "$Countries"},
{$group => {"_id":"$_id","Countries":{$push => "$Countries"}}}
])
Run Code Online (Sandbox Code Playgroud)
第一$unwind阶段产生结果:
{
"_id" : ObjectId("54a32e0fc2eaf05fc77a5ea4"),
"Countries" : [
"Spain",
"France"
]
}
{
"_id" : ObjectId("54a32e4ec2eaf05fc77a5ea5"),
"Countries" : [
"Spain"
]
}
{
"_id" : ObjectId("54a32e4ec2eaf05fc77a5ea5"),
"Countries" : [
"Russia",
"Egypt"
]
}
Run Code Online (Sandbox Code Playgroud)
第二$unwind阶段进一步扁平化Countries数组:
{ "_id" : ObjectId("54a32e0fc2eaf05fc77a5ea4"), "Countries" : "Spain" }
{ "_id" : ObjectId("54a32e0fc2eaf05fc77a5ea4"), "Countries" : "France" }
{ "_id" : ObjectId("54a32e4ec2eaf05fc77a5ea5"), "Countries" : "Spain" }
{ "_id" : ObjectId("54a32e4ec2eaf05fc77a5ea5"), "Countries" : "Russia" }
{ "_id" : ObjectId("54a32e4ec2eaf05fc77a5ea5"), "Countries" : "Egypt" }
Run Code Online (Sandbox Code Playgroud)
现在,最后$group阶段根据 来对记录进行分组_id,并将国家/地区名称累积在单个数组中。
{
"_id" : ObjectId("54a32e4ec2eaf05fc77a5ea5"),
"Countries" : [
"Spain",
"Russia",
"Egypt"
]
}
{
"_id" : ObjectId("54a32e0fc2eaf05fc77a5ea4"),
"Countries" : [
"Spain",
"France"
]
}
Run Code Online (Sandbox Code Playgroud)
如果您希望在文档中保留其他字段,则需要使用运算符显式指定国家/地区字段以外的字段名称(字段 1、字段 2 等)$first。您可以通过在阶段中指定集合的名称来写入/覆盖集合$out。
collection.aggregate([
{$unwind => "$Countries"},
{$unwind => "$Countries"},
{$group => {"_id":"$_id","Countries":{$push => "$Countries"},
"field1":{$first => "$field1"}}},
{$out => "collection"}
])
Run Code Online (Sandbox Code Playgroud)
您需要显式指定字段,以免出现冗余Countries字段。
您可以使用$$ROOT系统变量来存储整个文档,但这会使该Countries字段变得多余。一个在 外部doc,一个在 内部doc。
collection.aggregate([
{$unwind => "$Countries"},
{$unwind => "$Countries"},
{$group => {"_id":"$_id","Countries":{$push => "$Countries"},
"doc":{$first => "$$ROOT"}}},
{$out => "collection"}
])
Run Code Online (Sandbox Code Playgroud)
您的国家/地区数据格式不佳,因此您可以考虑对其进行转换。这是一个脚本,用于展平“国家”字段中的数组并将其保存为可以在 mongo shell 中运行的原始文档:
function flattenArray(inArr) {
var ret = [];
inArr.forEach(function(arr) {
if (arr.constructor.toString().indexOf("Array") > -1) {
ret = ret.concat(flattenArray(arr));
} else {
ret.push(arr);
}
});
return ret;
}
db.collection.find({
'Countries': {
'$exists': true
}
}).forEach(function(doc){
doc.Countries = flattenArray(doc.Countries);
db.collection.save(doc);
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1999 次 |
| 最近记录: |