当前位置: 首页 > 知识库问答 >
问题:

展开并忽略重复后的组元素-MongoDB聚合

冯皓
2023-03-14

我使用聚合来展开一个数组,并按数组的每个元素分组,以对一些对应的值求和。

我的收藏是:

/* 1 */
{
    "_id" : ObjectId("59ce411c2708c97154d1319b"),
    "sourceMediumPath" : [ 
        {
            "nodeValue" : "(direct) / (none)"
        }, 
        {
            "nodeValue" : "(direct) / (none)"
        }
    ],
    "totalConversions" : 1,
    "totalConversionValue" : 171.6,
}

/* 2 */
{
    "_id" : ObjectId("59ce411c2708c97154d136a0"),
    "sourceMediumPath" : [ 
        {
            "nodeValue" : "google / cpc"
        }, 
        {
            "nodeValue" : "(direct) / (none)"
        }, 
        {
            "nodeValue" : "google / cpc"
        }
    ],
    "totalConversions" : 1,
    "totalConversionValue" : 151.8,
}

我想按sourceMedium分组。nodeValue和sum“totalConverions”和“totalConversionValue”,而不使用重复元素。

例如,通过使用展开、分组和和:

aggregation = Aggregation.newAggregation(
                    Aggregation.unwind("sourceMediumPath"),
                    Aggregation.group("sourceMediumPath.nodeValue")
                            .sum("totalConversions").as(Variables.TOTAL_CONNVERSIONS)
                            .sum("TotalConversionValue").as(Variables.TOTAL_CONVERSION_VALUE),

                    Aggregation.project("sourceMediumPath.nodeValue")
                            .andInclude(Variables.TOTAL_CONNVERSIONS, Variables.TOTAL_CONVERSION_VALUE)

对于“nodeValue”:(direct)/(none)“TotalConversions之和等于3,对于“google/cpc”之和等于1。因为它在执行展开操作时复制totalConversions和totalConversions。

有任何解决方案可以忽略重复,并且每个文档只有一个值。

我怎么能那么做?

共有2个答案

谭繁
2023-03-14

在Spring Data中,聚合投影管道中的相交数组通过应用相同的数组来完成这项工作。

aggregation = Aggregation.newAggregation(
               Aggregation.project().and("sourceMediumPathnodeValue").intersectsArrays("sourceMediumPathnodeValue").as("Intersection").andInclude(...),
                    Aggregation.unwind("Intersection"),
                    Aggregation.group("Intersection")
                            .sum("totalConversions").as("totalConversions")
                            .sum("TotalConversionValue").as(TotalConversionValue"),
                    Aggregation.project("sourceMediumPath.nodeValue")
                            .andInclude("totalConversions", TotalConversionValue")

                        new OutOperation("OutputCollection")
                ).withOptions(Aggregation.newAggregationOptions().allowDiskUse(true).build());

非常感谢你的帮助

公良信然
2023-03-14

您可以使用$addField在$unroll阶段之前添加$addField以使用$setIntersect创建一个唯一值数组,并将此字段展开如下:

db.collection.aggregate( [
    { $addFields: {
        sourceMediumUniquePath: { $setIntersection: [ 
            "$sourceMediumPath", 
            "$sourceMediumPath" 
        ] }
    } },
    { $unwind: "$sourceMediumUniquePath" },
    ... rest of the pipeline ...
])

更新:

如果不支持$添加字段,则可以将其替换为$项目阶段。唯一的缺点是,您需要列出在以后阶段需要的所有字段。例如。:

db.collection.aggregate( [
    { $project: {
        sourceMediumUniquePath: { $setIntersection: [ 
            "$sourceMediumPath", 
            "$sourceMediumPath" 
        ] },
        totalConversions: 1,
        totalConversionValue: 1
    } },
    { $unwind: "$sourceMediumUniquePath" },
    ... rest of the pipeline ...
])
 类似资料:
  • 我正在使用MongoDB聚合框架展开一个数组,该数组有重复项,我需要在进一步分组时忽略这些重复项。 我如何才能做到这一点?

  • 我在mongodb中的聚合有点问题; 收藏uczelna: 我的合计: 我想找到所有的医生(doktorzy)妇女(名字的最后一个字母a)在一所学校(uczelna)。imie(姓名) 告诉我我做错了什么,谢谢

  • 我想插入一批文档,其中一些已经存在于集合中。所以我想要的是忽略它们,或者对我来说更好的解决方案是在例外情况下,我想记录哪个文档是重复的,如果可能的话,继续插入下一个文档。 我看到了几个类似的问题,但没有一个解决了这个问题。 我的代码如下所示: 任何帮助都将不胜感激。

  • 现在,如果我使用以下代码进行比较,我将在XMLUnit的帮助下相互比较两个xml文件 现在它给出了:预期的属性值'02',但是'01',但我不希望有差异,我希望表id是唯一的,如果在另一个文件中看到相同的表id,则只检查本例中的Main-Element:table->包含什么。

  • 本文向大家介绍system.reactive 忽略重复值,包括了system.reactive 忽略重复值的使用技巧和注意事项,需要的朋友参考一下 示例 有两个用于过滤重复项的运算符: 您还可以传递谓词:            

  • 在Spring MVC中,我需要将空字符串()视为。这是因为我发现,当我编辑一个表单字段(带有Angular的ng-model),该字段最初是,然后将其擦除为空白时,Angular将以空字符串的形式发送该bean属性。如果我不接触这样的null值,它将不会在JSON有效负载中发送,因此被视为null。