在聚合管道的项目阶段排除嵌套对象 属性 时遇到问题
Having trouble in excluding nested object property in project stage in aggregation pipeline
我有一个聚合查询,其中 returns 问题数组根据文档类型具有不同的架构。文件格式如下。有些问题可能看起来像这样
{
"_id": "ID01",
"Description": "1.Any Question?",
"answer": { "option05": "E. " },
"options": {
"option01": "A.",
"option02": "B.",
"option03": "C.",
"option04": "D.",
"option05": "E."
},
"type": "1",
"score": 10
},
部分问题结构如下
{
"_id": "ID02",
"Description": "Question Description.",
"emq": {
"emq3": {
"answer": "option12",
"explanation": "",
"question": "1 Any Qstn?"
},
"emq4": {
"answer": "option03",
"explanation": "",
"question": "2 Any Qstn?"
},
"emq5": {
"answer": "option06",
"explanation": "",
"question": "3 Any Qstn?"
}
},
"options": {
"option01": "",
"option02": "",
"option03": "",
"option04": "",
},
"type": "2",
"score": 100
},
我使用了以下聚合管道来隐藏问题中的答案,(相关架构已迁移,我无法更改其结构)
聚合管道
{
$lookup: {
from: 'questions',
let: {
question_id: { $toObjectId: '$qId' },
score: '$score',
},
pipeline: [
{
$match: {
$expr: {
$eq: ['$_id', '$$question_id'],
},
},
},
{
$project: {
answer: {
$cond: {
if: { $eq: ['$type', '1'] },
then: 0,
else: {
$cond: {
if: { $eq: ['$type', '3'] },
then: {
$cond: {
if: {
emq: {
regex: /^emq\d+$/,
},
},
then: 0,
else: 1,
},
},
else: 1,
},
},
},
},
Description: 1,
options: 1,
type: 1,
emq: 1,
score: 1,
},
},
}
它适用于类型 1 的问题,但不幸的是我无法隐藏类型 2 的答案,因为它们不仅在 'emq' 对象中而且也在嵌套的 'emq3' 对象中在字符串 'emq' 的末尾使用动态数字,我应用了正则表达式,但不知何故我无法在 emq3 对象中投影答案,是否有实现以下结果来隐藏两个问题的答案
{
"_id": "ID01",
"Description": "1.Any Question?",
"options": {
"option01": "A.",
"option02": "B.",
"option03": "C.",
"option04": "D.",
"option05": "E."
},
"type": "1",
"score": 10
},
{
"_id": "ID02",
"Description": "Question Description.",
"emq": {
"emq3": {
"question": "1 Any Qstn?"
},
"emq4": {
"question": "2 Any Qstn?"
},
"emq5": {
"question": "3 Any Qstn?"
}
},
"options": {
"option01": "",
"option02": "",
"option03": "",
"option04": "",
},
"type": "2",
"score": 100
},
您可以在聚合管道中执行以下操作:
- 使用
$objectToArray
将对象emq
转换为k-v元组数组
$project
删除字段 answer
和 explanation
convert the array
emq`回对象
db.collection.aggregate([
{
"$addFields": {
"emq": {
"$objectToArray": "$emq"
}
}
},
{
"$project": {
"emq.v.answer": false,
"emq.v.explanation": false,
"answer": false
}
},
{
"$addFields": {
"emq": {
"$arrayToObject": "$emq"
}
}
},
{
"$addFields": {
emq: {
"$cond": {
"if": {
$eq: [
"$emq",
null
]
},
"then": "$$REMOVE",
"else": "$emq"
}
}
}
}
])
这里是Mongo playground供大家参考。
我有一个聚合查询,其中 returns 问题数组根据文档类型具有不同的架构。文件格式如下。有些问题可能看起来像这样
{
"_id": "ID01",
"Description": "1.Any Question?",
"answer": { "option05": "E. " },
"options": {
"option01": "A.",
"option02": "B.",
"option03": "C.",
"option04": "D.",
"option05": "E."
},
"type": "1",
"score": 10
},
部分问题结构如下
{
"_id": "ID02",
"Description": "Question Description.",
"emq": {
"emq3": {
"answer": "option12",
"explanation": "",
"question": "1 Any Qstn?"
},
"emq4": {
"answer": "option03",
"explanation": "",
"question": "2 Any Qstn?"
},
"emq5": {
"answer": "option06",
"explanation": "",
"question": "3 Any Qstn?"
}
},
"options": {
"option01": "",
"option02": "",
"option03": "",
"option04": "",
},
"type": "2",
"score": 100
},
我使用了以下聚合管道来隐藏问题中的答案,(相关架构已迁移,我无法更改其结构)
聚合管道
{
$lookup: {
from: 'questions',
let: {
question_id: { $toObjectId: '$qId' },
score: '$score',
},
pipeline: [
{
$match: {
$expr: {
$eq: ['$_id', '$$question_id'],
},
},
},
{
$project: {
answer: {
$cond: {
if: { $eq: ['$type', '1'] },
then: 0,
else: {
$cond: {
if: { $eq: ['$type', '3'] },
then: {
$cond: {
if: {
emq: {
regex: /^emq\d+$/,
},
},
then: 0,
else: 1,
},
},
else: 1,
},
},
},
},
Description: 1,
options: 1,
type: 1,
emq: 1,
score: 1,
},
},
}
它适用于类型 1 的问题,但不幸的是我无法隐藏类型 2 的答案,因为它们不仅在 'emq' 对象中而且也在嵌套的 'emq3' 对象中在字符串 'emq' 的末尾使用动态数字,我应用了正则表达式,但不知何故我无法在 emq3 对象中投影答案,是否有实现以下结果来隐藏两个问题的答案
{
"_id": "ID01",
"Description": "1.Any Question?",
"options": {
"option01": "A.",
"option02": "B.",
"option03": "C.",
"option04": "D.",
"option05": "E."
},
"type": "1",
"score": 10
},
{
"_id": "ID02",
"Description": "Question Description.",
"emq": {
"emq3": {
"question": "1 Any Qstn?"
},
"emq4": {
"question": "2 Any Qstn?"
},
"emq5": {
"question": "3 Any Qstn?"
}
},
"options": {
"option01": "",
"option02": "",
"option03": "",
"option04": "",
},
"type": "2",
"score": 100
},
您可以在聚合管道中执行以下操作:
- 使用
$objectToArray
将对象 $project
删除字段answer
和explanation
convert the array
emq`回对象
emq
转换为k-v元组数组
db.collection.aggregate([
{
"$addFields": {
"emq": {
"$objectToArray": "$emq"
}
}
},
{
"$project": {
"emq.v.answer": false,
"emq.v.explanation": false,
"answer": false
}
},
{
"$addFields": {
"emq": {
"$arrayToObject": "$emq"
}
}
},
{
"$addFields": {
emq: {
"$cond": {
"if": {
$eq: [
"$emq",
null
]
},
"then": "$$REMOVE",
"else": "$emq"
}
}
}
}
])
这里是Mongo playground供大家参考。