mongodb - MongoDB 在 $group $push 中创建数组数组而不是平面数组
问题描述
我试图在 $unwind 操作之后对一组文档进行分组。我的文件如下所示:
{
"_id" : ObjectId("5cdb5b5acadf5100019da2f4"),
"allowedLocations" : [
{
"type" : "country",
"value" : "world",
"label" : "World"
}
],
"disallowedLocations" : [
{
"type" : "country",
"value" : "CF",
"label" : "Central African Republic"
},
{
"type" : "country",
"value" : "CN",
"label" : "China"
}
],
}
{
"_id" : ObjectId("5cdb5b5acadf5100019da2f4"),
"allowedLocations" : [
{
"type" : "country",
"value" : "US",
"label" : "United States of America"
}
],
"disallowedLocations" : [
{
"type" : "country",
"value" : "CA",
"label" : "Canada"
},
{
"type" : "country",
"value" : "MX",
"label" : "Mexico"
}
],
}
我想按 _id 对它们进行分组,然后将 allowedLocations 和 disallowedLocations 数组连接成一个。我的管道中的小组赛阶段如下所示:
{
"$group" : {
"_id" : "$_id",
"allowedLocations" : {
"$push" : "$allowedLocations"
},
"disallowedLocations" : {
"$push" : "disallowedLocations"
}
}
}
问题是,我得到的结果不是两个数组串联的文档,而是一个数组数组,数组的每个元素都是每个文档的数组:
{
"_id" : ObjectId("5cdb5b5acadf5100019da2f4"),
"allowedLocations" : [
[
{
"type" : "country",
"value" : "US",
"label" : "United States of America"
}
],
[
{
"type" : "country",
"value" : "world",
"label" : "World"
}
],
],
"disallowedLocations" : [
[
{
"type" : "country",
"value" : "CF",
"label" : "Central African Republic"
},
{
"type" : "country",
"value" : "CN",
"label" : "China"
}
],
[
{
"type" : "country",
"value" : "CA",
"label" : "Canada"
},
{
"type" : "country",
"value" : "MX",
"label" : "Mexico"
}
]
}
}
有没有办法产生一个只有对象作为元素的平面数组?在推送之前我也尝试过使用 $concatArrays ,但这会在数组中创建更多数组。
解决方案
这里有两个解决方案。您可以在两个数组上运行$unwind以获取单个allowed
和disallowed
location
每个文档,然后运行$group阶段:
db.col.aggregate([
{
$unwind: "$allowedLocations"
},
{
$unwind: "$disallowedLocations"
},
{
"$group" : {
"_id" : "$_id",
"allowedLocations" : {
"$addToSet" : "$allowedLocations"
},
"disallowedLocations" : {
"$addToSet" : "$disallowedLocations"
}
}
}
])
或者你可以先运行你的$group然后使用$reduce来展allowedLocations
平和disallowedLocations
:
db.col.aggregate([
{
"$group" : {
"_id" : "$_id",
"allowedLocations" : {
"$push" : "$allowedLocations"
},
"disallowedLocations" : {
"$push" : "$disallowedLocations"
}
}
},
{
$project: {
_id: 1,
allowedLocations: {
$reduce: {
input: "$allowedLocations",
initialValue: [],
in: { $concatArrays: [ "$$value", "$$this" ] }
}
},
disallowedLocations: {
$reduce: {
input: "$disallowedLocations",
initialValue: [],
in: { $concatArrays: [ "$$value", "$$this" ] }
}
}
}
}
])
推荐阅读
- dmarc - 从“mailer daemon@report domain submitter esa1.hc3329-29.iphmx”收到的电子邮件是 DMARC 报告吗?
- c# - 如何根据父属性中的列表项声明层次网格?
- xaml - 有没有办法在 Xamarin.Forms Shell 顶部选项卡中显示图标?
- javascript - 单击按钮一次显示一个列表
- javascript - 使用角度 8 中的 @input 装饰器将数据从父组件传递到子组件
- reactjs - Redux 存储在集成测试期间未更新
- javascript - 来自子组件的 Vue ref 调用方法返回未定义的方法(v-for)
- r - R - IMDb 数据集文件 - 如何合并每部电影的线条
- python - 如何在 python 中使用 selenium 循环遍历这些元素并获得 XPATH 值作为回报?
- ansible - 在 ansible play 中获取当前失败/跳过/正常任务的数量