Overview :
我正在处理的文档有两个嵌套数组 -contentMetaData
&text_content
。 在contentMetaData
,我们有text_content
和content_flag
。根据content_flag
的值,我需要隐藏text_content
中的特定字段。
要求:
- 如果
content_flag
为真,text_content
应该有一个孩子 -text_note
. - 如果
content_flag
为假,text_content
应该有一个孩子 -text_description
。 - 需要保留结构和其他细节。 不应
- 更新文档;这些值只需要在投影期间隐藏。
使用版本 :蒙戈 2.6
样本文档 :
{
"_id": ObjectId("56f8dd19e4b0365115927b0f"),
"contentId": "cbc91805-2faa-4eff-8f84-02547173c152",
"contentMetaData": [
{
"_id": "1574b58f-b7fa-4cd5-b34f-98beeb657c97",
"name": "text_content",
"attributes": [],
"children": [
{
"_id": "97340ecf-fdbd-41e5-a6b2-01cc542f16ee",
"name": "text_note",
"value": "abc",
"type": "java.lang.String",
"attributes": [],
"children": [],
"noOfChildren": 0,
"positionIndex": 1
},
{
"_id": "19c5a3fb-54a2-4368-a89d-ea1d2554402d",
"name": "text_description",
"value": "def",
"type": "java.lang.String",
"attributes": [],
"children": [],
"noOfChildren": 0,
"positionIndex": 2
}
],
"noOfChildren": 2,
"positionIndex": 1
},
{
"_id": "4e8ef7c9-cffd-4b36-9109-89b263dff3c8",
"name": "content_flag",
"value": "true",
"type": "java.lang.String",
"attributes": [],
"children": [],
"noOfChildren": 0,
"positionIndex": 2
}
]
}
示例输出:
{
"_id": ObjectId("56f8dd19e4b0365115927b0f"),
"contentId": "cbc91805-2faa-4eff-8f84-02547173c152",
"contentMetaData": [
{
"_id": "1574b58f-b7fa-4cd5-b34f-98beeb657c97",
"name": "text_content",
"attributes": [],
"children": [
{
"_id": "97340ecf-fdbd-41e5-a6b2-01cc542f16ee",
"name": "text_note",
"value": "abc",
"type": "java.lang.String",
"attributes": [],
"children": [],
"noOfChildren": 0,
"positionIndex": 1
}
],
"noOfChildren": 2,
"positionIndex": 1
},
{
"_id": "4e8ef7c9-cffd-4b36-9109-89b263dff3c8",
"name": "content_flag",
"value": "true",
"type": "java.lang.String",
"attributes": [],
"children": [],
"noOfChildren": 0,
"positionIndex": 2
}
]
}
我尝试使用$map
但没有用。我尝试使用$unwind
,但无法以所需的格式$push
数据。
示例 Mongo 代码 :
db.content.aggregate([
{
$project: {
_id: 1,
contentId: 1,
contentMetaData: 1
tempMetaData: "$contentMetaData"
}
},
{
$unwind: "$contentMetaData"
},
{
$match: {
"contentMetaData.name": "content_flag"
}
},
{
$project: {
_id: 1,
contentId: 1,
contentMetaData: "$tempMetaData",
content_flag_value: "$contentMetaData.value"
}
},
{
$project: {
_id: 1,
contentId: 1,
contentMetaData: 1,
tempMetaData: "$contentMetaData",
content_flag_value: 1
}
},
{
$unwind: "$contentMetaData"
},
{
$match: {
"contentMetaData.name": "text_content"
}
},
{
$project: {
_id: 1,
contentId: 1,
contentMetaData: 1,
tempMetaData: "$contentMetaData",
content_flag_value: 1,
text_content : "$contentMetaData.children",
temp_text_content: "$text_content"
}
},
{
$unwind: "$text_content"
},
{
$group:{
_id:"$_id",
contentId:{$first:"$contentId"},
text_content:
{$max:
{$cond:
[
{$eq: ["$content_flag_value", "true"]},
{$cond:
[{$or:[
{$eq: ["$text_content.name","wk_link_url"]},
{$eq: ["$text_content.name","wk_link_description"]}
]},
"$text_content",
null]
},
null
]
}
},
contentMetaData:{$first:"$contentMetaData"}
}
},
{
$group:{
_id:"$_id",
contentId:{$first:"$contentId"},
contentMetaData:{$push:{"text_content":"$text_content"}}
}
},
{
$project: {
_id: 0,
contentId: 1,
contentMetaData: 1
}
}]).pretty()
我是蒙戈的新手。有人可以帮助我解决这个问题吗?
您可以尝试以下聚合。
$map
与$setDifference
结合使用以提取text_content
并content_flag
阵列。
$unwind
content_flag
文档。
$map
将当前值保留在text_content
中,并结合$setDifference
$map
,以根据条件筛选children
。
$setUnion
将text_content
和content_flag
阵列重新联接到contentMetaData
db.collection.aggregate({
$project: {
_id: 1,
contentId: 1,
text_content: {
"$setDifference": [{
"$map": {
"input": "$contentMetaData",
"as": "text",
"in": {
"$cond": [{
$eq: ['$$text.name', "text_content"]
},
"$$text",
false
]
}
}
},
[false]
]
},
content_flag: {
"$setDifference": [{
"$map": {
"input": "$contentMetaData",
"as": "content",
"in": {
"$cond": [{
$eq: ['$$content.name', "content_flag"]
},
"$$content",
false
]
}
}
},
[false]
]
}
}
}, {
$unwind: "$content_flag"
}, {
$project: {
"_id": 1,
contentId: 1,
"contentMetaData": {
$setUnion: [{
$map: {
input: "$text_content",
as: "text",
in: {
"_id": "$$text._id",
"name": "$$text.name",
"attributes": "$$text.attributes",
"noOfChildren": "$$text.noOfChildren",
"positionIndex": "$$text.positionIndex",
"children": {
"$setDifference": [{
"$map": {
"input": "$$text.children",
"as": "child",
"in": {
"$cond": [{
"$cond": [{
$eq: ["$content_flag.value", "true"]
}, {
$eq: ["$$child.name", "text_note"]
}, {
$eq: ["$$child.name", "text_description"]
}]
},
"$$child",
false
]
}
}
},
[false]
]
}
}
}
},
["$content_flag"]
]
}
}
})
更新:
$map
与$setDifference
结合使用以提取content_flag
阵列。
$unwind
content_flag
文档。
$redact
一次遍历文档级别,递归查找name
字段,并根据条件执行$$DESCEND
和$$PRUNE
。
$project
格式化最终响应。
db.collection.aggregate({
$project: {
_id: 1,
contentId: 1,
contentMetaData: 1,
content_flag: {
"$setDifference": [{
"$map": {
"input": "$contentMetaData",
"as": "content",
"in": {
"$cond": [{
$eq: ['$$content.name', "content_flag"]
},
"$$content",
false
]
}
}
},
[false]
]
}
}
}, {
$unwind: "$content_flag"
}, {
$redact: {
$cond: [{
$or: [{
$eq: ["$name", "text_content"]
}, {
$not: "$name"
}, {
$eq: ["$name", "content_flag"]
}, {
$and: [{
$eq: ["$name", "text_note"]
}, {
$eq: ["$$ROOT.content_flag.value", "true"]
}]
}, {
$and: [{
$eq: ["$name", "text_description"]
}, {
$eq: ["$$ROOT.content_flag.value", "false"]
}]
}]
},
"$$DESCEND",
"$$PRUNE"
]
}
}, {
$project: {
_id: 1,
contentId: 1,
contentMetaData: 1
}
});