MongoDB 文档中文档的聚合过滤器
MongoDB Aggregation filter on documents within documents
你能帮我解决一个问题吗...
我有这个 json 但我只想 return 节点。
{
"_id":{
"userArea":NumberInt(4927)
},
"pages":{
"12":{
"page":NumberInt(2635),
"progress":"COMPLETED",
"progressType":"USER_PROGRESS",
"end":11
},
"13":{
"page":NumberInt(2627),
"progress":"COMPLETED",
"progressType":"USER_PROGRESS",
"end":ISODate("2018-04-19T15:04:29.000+0000")
}
"14":{
"page":NumberInt(2627),
"progress":"CANCELLED",
"progressType":"USER_PROGRESS",
"end":ISODate("2018-04-19T15:04:29.000+0000")
}
}
}
这样....没有header
"12":{
"page":NumberInt(2635),
"progress":"COMPLETED",
"progressType":"USER_PROGRESS",
"end":11
},
"13":{
"page":NumberInt(2627),
"progress":"COMPLETED",
"progressType":"USER_PROGRESS",
"end":ISODate("2018-04-19T15:04:29.000+0000")
}
你能帮帮我吗?我只需要过滤已完成的!!!
您可以使用此聚合查询:
- 首先使用
$objectToArray
生成一个数组,可以使用值v
过滤值。这是在 input
. 中完成的
- 然后使用该输入值,您可以过滤
progress
值不是 CANCELLED
的元素。并使用 $arrayToObject
再次转换为 object
db.collection.aggregate([
{
"$project": {
"pages": {
"$arrayToObject": {
"$filter": {
"input": {
"$objectToArray": "$pages"
},
"cond": {
"$ne": [
"$$this.v.progress",
"CANCELLED"
]
}
}
}
}
}
}
])
示例here
抱歉,我第一次尝试时读到“without header”,我以为你想使用 $replaceRoot
但我认为这个新查询就是你想要的(也避免了 $unwind
).
但我认为你说“without hedaer”是为了显示问题中简化的输出。此外,如果您无法输出 header,只需使用 $replaceRoot
添加一个新阶段。示例 here
您需要像 here
那样执行许多管道
db.collection.aggregate([
{
"$project": {
"p": {
"$objectToArray": "$pages"
}
}
},
{
"$unwind": "$p"
},
{
"$match": {
"p.v.progress": "COMPLETED"
}
},
{
"$group": {
"_id": "$_id",
"p": {
"$addToSet": "$p"
}
}
},
{
$project: {
"a": {
"$arrayToObject": "$p"
}
}
},
{
"$replaceRoot": {
"newRoot": "$a"
}
}
])
- 调整形状以便您可以应用滤镜。
- 再次分组以返回到您的原始架构。否则,您可以在 $match 管道停止。
如果可能,请更改架构,不要使用动态键。
你能帮我解决一个问题吗... 我有这个 json 但我只想 return 节点。
{
"_id":{
"userArea":NumberInt(4927)
},
"pages":{
"12":{
"page":NumberInt(2635),
"progress":"COMPLETED",
"progressType":"USER_PROGRESS",
"end":11
},
"13":{
"page":NumberInt(2627),
"progress":"COMPLETED",
"progressType":"USER_PROGRESS",
"end":ISODate("2018-04-19T15:04:29.000+0000")
}
"14":{
"page":NumberInt(2627),
"progress":"CANCELLED",
"progressType":"USER_PROGRESS",
"end":ISODate("2018-04-19T15:04:29.000+0000")
}
}
}
这样....没有header
"12":{
"page":NumberInt(2635),
"progress":"COMPLETED",
"progressType":"USER_PROGRESS",
"end":11
},
"13":{
"page":NumberInt(2627),
"progress":"COMPLETED",
"progressType":"USER_PROGRESS",
"end":ISODate("2018-04-19T15:04:29.000+0000")
}
你能帮帮我吗?我只需要过滤已完成的!!!
您可以使用此聚合查询:
- 首先使用
$objectToArray
生成一个数组,可以使用值v
过滤值。这是在input
. 中完成的
- 然后使用该输入值,您可以过滤
progress
值不是CANCELLED
的元素。并使用$arrayToObject
再次转换为 object
db.collection.aggregate([
{
"$project": {
"pages": {
"$arrayToObject": {
"$filter": {
"input": {
"$objectToArray": "$pages"
},
"cond": {
"$ne": [
"$$this.v.progress",
"CANCELLED"
]
}
}
}
}
}
}
])
示例here
抱歉,我第一次尝试时读到“without header”,我以为你想使用 $replaceRoot
但我认为这个新查询就是你想要的(也避免了 $unwind
).
但我认为你说“without hedaer”是为了显示问题中简化的输出。此外,如果您无法输出 header,只需使用 $replaceRoot
添加一个新阶段。示例 here
您需要像 here
那样执行许多管道db.collection.aggregate([
{
"$project": {
"p": {
"$objectToArray": "$pages"
}
}
},
{
"$unwind": "$p"
},
{
"$match": {
"p.v.progress": "COMPLETED"
}
},
{
"$group": {
"_id": "$_id",
"p": {
"$addToSet": "$p"
}
}
},
{
$project: {
"a": {
"$arrayToObject": "$p"
}
}
},
{
"$replaceRoot": {
"newRoot": "$a"
}
}
])
- 调整形状以便您可以应用滤镜。
- 再次分组以返回到您的原始架构。否则,您可以在 $match 管道停止。
如果可能,请更改架构,不要使用动态键。