node.js - Mongoose 按日期和值聚合
问题描述
我无法解决我在项目中遇到的问题。
首先,我有一个名为 Emotions 的 Schema,如下所示:
import mongoose from 'mongoose';
const EmotionSchema = new mongoose.Schema({
classification: {
type: String,
required: true,
},
probability: {
type: Number,
required: true,
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
}
}, {
timestamps: true,
});
export default mongoose.model('Emotion', EmotionSchema);
还有一些数据是这样的:
[
{
"_id": "61144a393c532f066725bd24",
"classification": "Feliz",
"probability": 0.98,
"user": "60eecfeba0810013e750cdbc",
"createdAt": "2021-08-11T22:07:53.331Z",
"updatedAt": "2021-08-11T22:07:53.331Z",
"__v": 0
},
{
"_id": "61144a46d30bd006fa2be702",
"classification": "Feliz",
"probability": 0.98,
"user": "60eecfeba0810013e750cdbc",
"createdAt": "2021-08-11T22:08:06.618Z",
"updatedAt": "2021-08-11T22:08:06.618Z",
"__v": 0
},
{
"_id": "611541dd62a7f214afab3ceb",
"classification": "Triste",
"probability": 0.9,
"user": "60eecfeba0810013e750cdbc",
"createdAt": "2021-08-12T15:44:29.150Z",
"updatedAt": "2021-08-12T15:44:29.150Z",
"__v": 0
},
{
"_id": "611541f762a7f214afab3cf5",
"classification": "Raiva",
"probability": 0.86,
"user": "60eecfeba0810013e750cdbc",
"createdAt": "2021-08-12T15:44:55.909Z",
"updatedAt": "2021-08-12T15:44:55.909Z",
"__v": 0
},
{
"_id": "6115420362a7f214afab3cf7",
"classification": "Neutro",
"probability": 0.99,
"user": "60eecfeba0810013e750cdbc",
"createdAt": "2021-08-12T15:45:07.297Z",
"updatedAt": "2021-08-12T15:45:07.297Z",
"__v": 0
},
{
"_id": "6115420462a7f214afab3cf9",
"classification": "Neutro",
"probability": 0.99,
"user": "60eecfeba0810013e750cdbc",
"createdAt": "2021-08-12T15:45:08.002Z",
"updatedAt": "2021-08-12T15:45:08.002Z",
"__v": 0
},
{
"_id": "611543d252be9a187c380e5d",
"classification": "Feliz",
"probability": 0.91,
"user": "60eecfeba0810013e750cdbc",
"createdAt": "2021-08-12T15:52:50.599Z",
"updatedAt": "2021-08-12T15:52:50.599Z",
"__v": 0
}
]
我想要的是:
首先按天对这些记录进行分组。之后,按分类计算值,但将这些分类分开。
像这样的东西:
[
{
"_id": "12/08/2021",
"feliz": 1,
"triste": 1,
"raiva": 1,
"neutro": 2,
"surpreso": 0,
},
{
"_id": "11/08/2021",
"feliz": 2,
"triste": 0,
"raiva": 0,
"neutro": 0,
"surpreso": 0,
}
]
我做了类似的事情,但它只适用于一个价值,例如“Feliz”。在代码中:
Emotion.aggregate([
{ $match:
{
user: user._id,
classification: "Feliz"
}
},
{ $group: {
_id : { $dateToString: { format: "%d/%m/%Y", date: "$createdAt" } },
feliz: { $sum: 1 }
}},
], function(err, results) {
if (err) throw err;
return res.json(results);
})
它返回:
[
{
"_id": "12/08/2021",
"feliz": 1
},
{
"_id": "11/08/2021",
"feliz": 4
}
]
还有一个问题:从客户端,我总是得到“分类”的值,例如:“Feliz”、“Triste”、“Surpreso”、“Raiva”、“Neutro”。那么在我的模式“Emotion”中添加一个枚举会更好吗?
(对不起我的英语,希望你能理解)。
解决方案
$group
按createdAt
日期和classification
,计数总和$group
by only 和 构造键值对中的andcreatedAt
的数组classification
count
$arrayToObject
将上述对象的键值对数组转换为对象格式
Emotion.aggregate([
{
$match: {
user: user._id,
classification: "Feliz"
}
},
{
$group: {
_id: {
createdAt: {
$dateToString: {
format: "%d/%m/%Y",
date: "$createdAt"
}
},
classification: "$classification"
},
count: { $sum: 1 }
}
},
{
$group: {
_id: "$_id.createdAt",
classifications: {
$push: {
k: "$_id.classification",
v: "$count"
}
}
}
},
{
$addFields: {
classifications: {
$arrayToObject: "$classifications"
}
}
}
],
function(err, results) {
if (err) throw err;
return res.json(results);
})
注意:当计数为 0 时,这不会返回分类!你需要在js中查询后执行此操作。
还有一个问题:从客户端,我总是得到“分类”的值,例如:“Feliz”、“Triste”、“Surpreso”、“Raiva”、“Neutro”。那么在我的模式“Emotion”中添加一个枚举会更好吗?
这取决于您的项目要求,您可以在枚举中设置这些值以限制输入。
推荐阅读
- python - 如何保持 Python 脚本运行以继续读取文本文件?
- .net - 如何在 Active Reports 15 中显示特定项目的特定图像
- c - Rust cdylib crate,将 dll 链接到 Windows 中的 C 程序
- php - 如何序列化布尔值?
- python - 如何在 Python 中更改网格的 UP-Vector?
- gpu - Pytorch Lightning 完全在 gpu 上使用小数据集进行训练
- java - Sonar:用方法引用替换这个 lambda。什么时候应该使用“stream()”?
- docker - 无法从 dockerized Nexus Repository 访问 LDAP 服务器
- reactjs - 无法在使用 Firebase 和 Stripe 的配置中获得付费状态
- c# - 连接到 Kubernetes 的桥不使用 Grpc 服务