Mongodb $addToSet的替代方案,用于处理数组中的元素(而不是整个数组)
我在MongoDB中有一个集合,其中的文档遵循以下模式:Mongodb $addToSet的替代方案,用于处理数组中的元素(而不是整个数组),mongodb,aggregation-framework,Mongodb,Aggregation Framework,我在MongoDB中有一个集合,其中的文档遵循以下模式: { "_id" : { "id" : "ID1", "type" : "TYPE1" }, "attrs" : [ { "name" : "ATTR1", "value" : "foo"
{
"_id" : {
"id" : "ID1",
"type" : "TYPE1"
},
"attrs" : [
{
"name" : "ATTR1",
"value" : "foo"
},
{
"name" : "ATTR2",
"type" : "bar"
},
...
{
"name" : "ATTRn",
"value" : "blabla"
}
]
}
集合中的每个文档表示一个实体(具有唯一的ID和类型)和一组属性。每个文档可以有不同数量的属性,甚至属于同一类型(即具有相同\u id.type
的两个文档可以有不同的属性集)
我想获得与给定类型关联的属性的名称(实际上是属性集的并集)。我正在尝试以下方法:
db.runCommand({aggregate: "col", pipeline: [ {$group: {_id: "$_id.type", attr: {$addToSet: "$attrs.name"}} }]})
其结果是:
{
"result" : [
{
"_id" : "TYPE1",
"attr" : [
[
"ATTR1",
"ATTR2",
"ATTR3"
],
[
"ATTR4",
"ATTR5"
]
]
},
...
],
"ok" : 1
}
问题是在添加数组元素时,$addToSet
不会逐个元素进行处理。相反,它将整个数组视为一个元素。因此,最后我得到的是一个“数组数组”,而我想要的是这样的东西:
{
"result" : [
{
"_id" : "TYPE1",
"attr" : [
"ATTR1",
"ATTR2",
"ATTR3",
"ATTR4",
"ATTR5"
]
},
...
],
"ok" : 1
}
要获得此结果,应如何重新格式化上述查询?在分组之前,您需要查看attrs
数组:
db.col.aggregate([
{$unwind:'$ATTR'},
{$group:{{U id:$\U id.type”,attr:{$addToSet:“$attr.name”}}
])
输出:
{
“结果”:[
{
“_id”:“类型1”,
“属性”:[
“ATTRn”,
“第2条”,
“属性1”
]
}
],
“好”:1
}
$unwind
复制每个文档,每个attr
元素复制一次。在分组之前,需要先复制attrs
数组:
db.col.aggregate([
{$unwind:'$ATTR'},
{$group:{{U id:$\U id.type”,attr:{$addToSet:“$attr.name”}}
])
输出:
{
“结果”:[
{
“_id”:“类型1”,
“属性”:[
“ATTRn”,
“第2条”,
“属性1”
]
}
],
“好”:1
}
$unwind
复制每个文档,每个attr
元素复制一次。再次查找Mongo v2.4+
$addToSet
与$each
结合使用,仅当您想添加尚未存在的数组项时,才能完美地保存和更新它们
{ $addToSet: { <field>: { $each: [ <value1>, <value2> ... ] } } }
{$addToSet:{:{$each:[,…]}}
参考资料:再次查找Mongo v2.4+
$addToSet
与$each
结合使用,仅当您想添加尚未存在的数组项时,才能完美地保存和更新它们
{ $addToSet: { <field>: { $each: [ <value1>, <value2> ... ] } } }
{$addToSet:{:{$each:[,…]}}
参考: