MongoDB动态条件过滤
我正在尝试创建一个表单生成器和生成器,并从生成的表单中收集答案。收集答案后,我想根据一些过滤参数对它们进行过滤,并获得每个类别的平均结果。
问题已绑定类别(attributeGroupOne&Two)。
我的答案有以下结构。
{
"form": [{
"_id": {
"$oid": "62295d028b6b895048b7da96"
},
"questionType": "lickert5",
"label": "deneme sorusu 1",
"attributeGroupTwo": "deneme kategorisi alt 2",
"attributeGroupOne": "deneme kategorisi",
"name": "Question_1",
"weight": 4,
"type": "radio",
"options": {
"1": "Çok Az",
"2": "Az",
"3": "Bazen",
"4": "Genellikle",
"5": "Her Zaman"
}
}, {
"_id": {
"$oid": "62295d028b6b895048b7da95"
},
"questionType": "lickert10",
"label": "deneme sorusu 2",
"attributeGroupTwo": "deneme alt 3",
"attributeGroupOne": "deneme kategorisi",
"name": "Question_2",
"weight": 4,
"type": "radio",
"options": {
"1": "1",
"2": "2",
"3": "3",
"4": "4",
"5": "5",
"6": "6",
"7": "7",
"8": "8",
"9": "9",
"10": "10"
}
}, {
"_id": {
"$oid": "62295d028b6b895048b7da94"
},
"questionType": "trueFalse",
"label": "deneme sorusu 3",
"attributeGroupTwo": "deneme alt 5",
"attributeGroupOne": "deneme kategorisi",
"name": "Question_3",
"weight": 4,
"type": "radio",
"options": {
"0": "Yanlış",
"10": "Doğru"
}
}, {
"_id": {
"$oid": "62295d028b6b895048b7da93"
},
"questionType": "lickert5",
"label": "deneme sorusu 4",
"attributeGroupTwo": "deneme main sub",
"attributeGroupOne": "deneme main 2",
"name": "Question_4",
"weight": 4,
"type": "radio",
"options": {
"1": "Çok Az",
"2": "Az",
"3": "Bazen",
"4": "Genellikle",
"5": "Her Zaman"
}
}],
"surveyName": "deneme formu",
"createdBy": {
"$oid": "61becc2c230fc12274683b6a"
},
"createdAt": {
"$date": "2022-03-10T02:05:54.039Z"
},
"updatedAt": {
"$date": "2022-03-10T02:05:54.039Z"
},
"__v": 0
}
https://i.sstatic.net/xT2Cq.png
无需额外过滤器,仅按过滤类别通过以下查询,我得到了我想要的报告。
.aggregate([
{ $unwind: '$answers' },
{
$group: {
_id: '$answers.SubCategory',
CalculatedWeight: { $avg: '$answers.CalculatedWeight' },
formId: { $first: formId }
}
},
{ $project: { _id: 1, CalculatedWeight: 1, formId: 1 } },
{ $out: 'results' }
])
结果:
{
"CalculatedWeight": 19.35483870967742,
"formId": {
"$oid": "62295d028b6b895048b7da92"
}
}
https://i.sstatic.net/HxqBe.png
我成功添加了年龄过滤与以下块
const docs = await model
.aggregate([
{
$match: {
$and: [
{ age: { $gt: minAge, $lt: maxAge } },
{ formId: { $eq: formId } }
]
}
},
{ $unwind: '$answers' },
{
$group: {
_id: '$answers.SubCategory',
CalculatedWeight: { $avg: '$answers.CalculatedWeight' },
formId: { $first: formId }
}
},
{ $project: { _id: 1, CalculatedWeight: 1, formId: 1 } },
{ $out: 'results' }
])
但我有 5 个过滤器,分别是性别、部门、年龄、工作年限和教育水平。如果可能的话,我希望能够将它们与动态查询结合起来,但我不想编写 120 个 if 案例来组合它们。我想不出一种以编程方式根据过滤器进行过滤和计算的方法。
先感谢您。问题本身可能不太清楚,抱歉。如果您指出不足之处,我可以详细说明。
编辑: 过滤器类型如下所示。年龄和工作年限将是一个具有最小值和最大值的时期。如果可能的话,我希望能够组合所有过滤器类型,但由于条目池很小~200,这可能在统计上不合理。最常见的过滤器组合是:性别-部门-年龄、工作年限-部门、教育-性别。
过滤器: 性别:字符串 - 枚举 部门:字符串 - 枚举 年龄:数字 - 最小和最大 工作年限:数字 - 最小和最大 教育:字符串 - 枚举
I am trying to create a form builder and generator and from generated forms, I will collect answers. After collecting answers I want to filter them according to some filter parameters and get average results for each category.
Questions have categories(attributeGroupOne&Two) bind to them.
I have the following structure for my answers.
{
"form": [{
"_id": {
"$oid": "62295d028b6b895048b7da96"
},
"questionType": "lickert5",
"label": "deneme sorusu 1",
"attributeGroupTwo": "deneme kategorisi alt 2",
"attributeGroupOne": "deneme kategorisi",
"name": "Question_1",
"weight": 4,
"type": "radio",
"options": {
"1": "Çok Az",
"2": "Az",
"3": "Bazen",
"4": "Genellikle",
"5": "Her Zaman"
}
}, {
"_id": {
"$oid": "62295d028b6b895048b7da95"
},
"questionType": "lickert10",
"label": "deneme sorusu 2",
"attributeGroupTwo": "deneme alt 3",
"attributeGroupOne": "deneme kategorisi",
"name": "Question_2",
"weight": 4,
"type": "radio",
"options": {
"1": "1",
"2": "2",
"3": "3",
"4": "4",
"5": "5",
"6": "6",
"7": "7",
"8": "8",
"9": "9",
"10": "10"
}
}, {
"_id": {
"$oid": "62295d028b6b895048b7da94"
},
"questionType": "trueFalse",
"label": "deneme sorusu 3",
"attributeGroupTwo": "deneme alt 5",
"attributeGroupOne": "deneme kategorisi",
"name": "Question_3",
"weight": 4,
"type": "radio",
"options": {
"0": "Yanlış",
"10": "Doğru"
}
}, {
"_id": {
"$oid": "62295d028b6b895048b7da93"
},
"questionType": "lickert5",
"label": "deneme sorusu 4",
"attributeGroupTwo": "deneme main sub",
"attributeGroupOne": "deneme main 2",
"name": "Question_4",
"weight": 4,
"type": "radio",
"options": {
"1": "Çok Az",
"2": "Az",
"3": "Bazen",
"4": "Genellikle",
"5": "Her Zaman"
}
}],
"surveyName": "deneme formu",
"createdBy": {
"$oid": "61becc2c230fc12274683b6a"
},
"createdAt": {
"$date": "2022-03-10T02:05:54.039Z"
},
"updatedAt": {
"$date": "2022-03-10T02:05:54.039Z"
},
"__v": 0
}
https://i.sstatic.net/xT2Cq.png
Without additional filter just by filtering category with following query I am getting reports that I wanted.
.aggregate([
{ $unwind: '$answers' },
{
$group: {
_id: '$answers.SubCategory',
CalculatedWeight: { $avg: '$answers.CalculatedWeight' },
formId: { $first: formId }
}
},
{ $project: { _id: 1, CalculatedWeight: 1, formId: 1 } },
{ $out: 'results' }
])
results:
{
"CalculatedWeight": 19.35483870967742,
"formId": {
"$oid": "62295d028b6b895048b7da92"
}
}
https://i.sstatic.net/HxqBe.png
I successfully added age filtering with following block
const docs = await model
.aggregate([
{
$match: {
$and: [
{ age: { $gt: minAge, $lt: maxAge } },
{ formId: { $eq: formId } }
]
}
},
{ $unwind: '$answers' },
{
$group: {
_id: '$answers.SubCategory',
CalculatedWeight: { $avg: '$answers.CalculatedWeight' },
formId: { $first: formId }
}
},
{ $project: { _id: 1, CalculatedWeight: 1, formId: 1 } },
{ $out: 'results' }
])
But I have 5 filters that are, gender, department, age, working years, and education level. If possible I want to be able to combine them with dynamic querying but I don't want to write 120 if cases for combining them. I can't think a way to programmatically filter and calculate according to filters.
Thank you in advance. The question itself might be unclear, sorry about it. I can elaborate if you point out where it is lacking.
Edit:
Filter types can be seen below. Age and working years will be a period with min and max values. If possible I want to be able to combine all filter types but it will probably statistically unreasonable due to the small pool of entries ~200. Most common combinations for filters are: Gender-Department-Age, Working Years- Department, Education - Gender.
Filters:
gender: String - enum
department: String - enum
age: Number - Min and Max
working years: Number - Min and Max
education: String - enum
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于其他遇到同样问题的人,我是这样解决的。
在我的情况下,由于只有匹配查询会发生变化,因此我根据使用以下代码获得的查询参数构造了匹配查询。
输出:
然后将 mongoose 与它一起使用
For anyone else struggling with the same thing, I figured it out this way.
In my situation since only the match query is subject to change I constructed match queries according to query parameters I am getting with following code.
output:
Then use mongoose with it