聚合注释不适用于展开和匹配

Aggregation Annotation Not Working With Unwind and Match

我正在尝试 运行 使用 Spring Boot 和 MongoDB 的自定义聚合查询 returns 子文档中匹配特定字段的总和标准。

目前,我有一个查询returns一个子文档中字段的总和,但没有考虑条件的匹配。

工作查询:

@Aggregation(pipeline = {"{'$project': {'_id': '$_id', 'date': '$date', \n" +
            "      'confirmed': {'$sum': '$states.confirmed'}, \n" +
            "      'deaths': {'$sum': '$states.deaths'}, \n" +
            "      'recovered': {'$sum': '$states.recovered'}, \n" +
            "      'active': {'$sum': '$states.active'}}}}"
})
AggregationResults<LineChart> aggregateAllStates(Sort sort);

Returns:

[
    {
        "date": "2020-04-12",
        "confirmed": 555613,
        "deaths": 22107,
        "active": 500306,
        "recovered": 67139
    },
    {
        "date": "2020-04-13",
        "confirmed": 580876,
        "deaths": 23633,
        "active": 615609,
        "recovered": 78924
    },
    {
        "date": "2020-04-14",
        "confirmed": 607926,
        "deaths": 25931,
        "active": 534076,
        "recovered": 85408
    },
etc...
]

下一个聚合不起作用:

@Aggregation(pipeline = {"{'$unwind':{path:'$states'}},\n" +
            "  {'$match': {'states.state': 'alabama'}},\n" +
            "  {'$project':{_id:'$_id', date: '$date',\n" +
            "    confirmed: {'$sum': '$states.confirmed'},\n" +
            "    active: {'$sum': '$states.active'},\n" +
            "    deaths: {'$sum': '$states.deaths'},\n" +
            "    recovered: {'$sum': '$states.recovered'}\n" +
            "  }}"
})
AggregationResults<LineChart> aggregateOneState(String name, Sort sort);

Returns:

[
    {
        "date": "2020-04-12",
        "confirmed": null,
        "deaths": null,
        "active": null,
        "recovered": null
    },
    {
        "date": "2020-04-12",
        "confirmed": null,
        "deaths": null,
        "active": null,
        "recovered": null
    },
    {
        "date": "2020-04-12",
        "confirmed": null,
        "deaths": null,
        "active": null,
        "recovered": null
    },
etc..
]

运行 mongo shell 中的这个查询工作得很好。在 Spring 中,它 returns 更多的数据(很确定它正在返回展开的数据),所有字段都为空。

db.us_collection.aggregate([
  {'$unwind':{path:'$states'}},
  {'$match': {'states.state': 'alabama'}},
  {'$project':{_id:'$_id', date: '$date',
    confirmed: {'$sum': '$states.confirmed'},
    active: {'$sum': '$states.active'},
    deaths: {'$sum': '$states.deaths'},
    recovered: {'$sum': '$states.recovered'}
  }},
  {'$sort':{date:-1}}
  ])

编辑:

数据在 MongoDB

中的样子
[
    {
        "id": "6017455f7517801dda88bc56",
        "date": "2020-04-12",
        "states": [
            {
                "state": "alabama",
                "confirmed": 3667,
                "deaths": 93,
                "recovered": 0,
                "active": 3470,
                "incident_rate": 75.98802021,
                "mortality_rate": 2.610159978
            },
            {
                "state": "alaska",
                "confirmed": 272,
                "deaths": 8,
                "recovered": 66,
                "active": 264,
                "incident_rate": 45.50404936,
                "mortality_rate": 2.941176471
            },
            {
                "state": "arizona",
                "confirmed": 3542,
                "deaths": 115,
                "recovered": 0,
                "active": 3427,
                "incident_rate": 48.66242224,
                "mortality_rate": 3.246753247
            },
            // continues list of states in same format
        ]
    },
    // more documents in same layout for different days
]

逗号放错地方了。

如果在 @Aggregation 注释中有一个多步查询,那么它们必须用逗号分隔 在字符串外部 .

无效查询示例:

@Aggregation(pipeline = {"{'$unwind':{path:'$states'}},\n" +
            "  {'$match': {'states.state': 'alabama'}},\n" +
            "  {'$project':{_id:'$_id', date: '$date',\n" +
            "    confirmed: {'$sum': '$states.confirmed'},\n" +
            "    active: {'$sum': '$states.active'},\n" +
            "    deaths: {'$sum': '$states.deaths'},\n" +
            "    recovered: {'$sum': '$states.recovered'}\n" +
            "  }}"
})

请注意分隔 $unwind$match$prject 的逗号都在字符串中。

工作聚合查询示例:

@Aggregation(pipeline = {"{'$unwind':{path:'$states'}}",
            "  {'$match': {'states.state': 'alabama'}}",
            "  {'$project':{_id:'$_id', date: '$date',\n" +
            "    confirmed: {'$sum': '$states.confirmed'},\n" +
            "    active: {'$sum': '$states.active'},\n" +
            "    deaths: {'$sum': '$states.deaths'},\n" +
            "    recovered: {'$sum': '$states.recovered'}\n" +
            "  }}"
})

现在请注意,分隔逗号位于字符串之外。

我也听取了@prasad_ 的建议并删除了 $unwind 而是使用过滤器来加速聚合。

这是我最终的工作聚合查询:

@Aggregation(pipeline = {"" +
            "{'$project': {'_id': '$_id', 'date': '$date', \n" +
            "      'states': {'$filter': {\n" +
            "          'input': '$states', \n" +
            "          'as': 'item', \n" +
            "          'cond': {'$eq': ['$$item.state', '?0']}}}}" +
            "}",
            "{'$project': {'_id': '$_id', 'date': '$date', \n" +
            "      'confirmed': {'$sum': '$states.confirmed'}, \n" +
            "      'deaths': {'$sum': '$states.deaths'}, \n" +
            "      'recovered': {'$sum': '$states.recovered'}, \n" +
            "      'active': {'$sum': '$states.active'}}}" +
            "}"
})
AggregationResults<LineChart> aggregateOneState(String name, Sort sort);