MongoDB - 如何使用 $graphLookup,然后使用 $group,之后使用 $sort
MongoDB - How to use $graphLookup then $group and $sort after
假设我有这个数据集:
[
{
_id: '1',
name: 'test1',
children: ['test2', so on...],
status: 'enabled',
version: 1,
},
{
_id: '2',
name: 'test2',
children: [],
status: 'enabled',
version: 1,
},
{
_id: '3',
name: 'test2',
children: ['test3'],
status: 'enabled',
version: 2,
},
{
_id: '4',
name: 'test2',
children: [],
status: 'disabled',
version: 3,
},
{
_id: '5',
name: 'test3',
children: [],
status: 'enabled',
version: 1,
}
]
我需要做的是获取 _id=1
项的子项和 return 启用项和最高版本。
有没有办法让我通过聚合阶段简单地完成它,或者我必须通过代码手动完成?
我当前的聚合查询:
db.Collection.aggregate([
{
$match: { name: 'test1', status: 'enabled' }
},
{
$graphLookup: {
from: "Collection",
startWith: "$children",
connectFromField: "children",
connectToField: "name",
as: "spreadChildren",
restrictSearchWithMatch: {
status: 'enabled'
}
}
}
])
这是预期的结果:
[
{
name: 'test1',
children: ['test2'],
status: 'enabled',
version: 1,
spreadChildren: [
{
_id: '3',
name: 'test2',
children: [],
status: 'enabled',
version: 2,
},
]
}
]
您可以在聚合管道中执行以下操作:
$unwind
$graphLookup
结果。
$sort
来自 version
$group
在 spreadChildren.name
级别并保留所有字段;使用 $first
保留最大的 version
元素
$group
再次达到 _id
级别以恢复到预期输出
db.collection.aggregate([
{
$match: {
name: "test1",
status: "enabled"
}
},
{
$graphLookup: {
from: "collection",
startWith: "$children",
connectFromField: "children",
connectToField: "name",
as: "spreadChildren",
restrictSearchWithMatch: {
status: "enabled"
}
}
},
{
"$unwind": "$spreadChildren"
},
{
$sort: {
"spreadChildren.version": -1
}
},
{
$group: {
_id: {
_id: "$_id",
name: "$spreadChildren.name"
},
children: {
$first: "$children"
},
name: {
$first: "$name"
},
spreadChildren: {
$first: "$spreadChildren"
},
status: {
$first: "$status"
},
version: {
$first: "$version"
}
}
},
{
$group: {
_id: "$_id._id",
children: {
$first: "$children"
},
name: {
$first: "$name"
},
spreadChildren: {
$push: "$spreadChildren"
},
status: {
$first: "$status"
},
version: {
$first: "$version"
}
}
}
])
这里是Mongo playround供您参考。
假设我有这个数据集:
[
{
_id: '1',
name: 'test1',
children: ['test2', so on...],
status: 'enabled',
version: 1,
},
{
_id: '2',
name: 'test2',
children: [],
status: 'enabled',
version: 1,
},
{
_id: '3',
name: 'test2',
children: ['test3'],
status: 'enabled',
version: 2,
},
{
_id: '4',
name: 'test2',
children: [],
status: 'disabled',
version: 3,
},
{
_id: '5',
name: 'test3',
children: [],
status: 'enabled',
version: 1,
}
]
我需要做的是获取 _id=1
项的子项和 return 启用项和最高版本。
有没有办法让我通过聚合阶段简单地完成它,或者我必须通过代码手动完成?
我当前的聚合查询:
db.Collection.aggregate([
{
$match: { name: 'test1', status: 'enabled' }
},
{
$graphLookup: {
from: "Collection",
startWith: "$children",
connectFromField: "children",
connectToField: "name",
as: "spreadChildren",
restrictSearchWithMatch: {
status: 'enabled'
}
}
}
])
这是预期的结果:
[
{
name: 'test1',
children: ['test2'],
status: 'enabled',
version: 1,
spreadChildren: [
{
_id: '3',
name: 'test2',
children: [],
status: 'enabled',
version: 2,
},
]
}
]
您可以在聚合管道中执行以下操作:
$unwind
$graphLookup
结果。$sort
来自version
$group
在spreadChildren.name
级别并保留所有字段;使用$first
保留最大的version
元素$group
再次达到_id
级别以恢复到预期输出
db.collection.aggregate([
{
$match: {
name: "test1",
status: "enabled"
}
},
{
$graphLookup: {
from: "collection",
startWith: "$children",
connectFromField: "children",
connectToField: "name",
as: "spreadChildren",
restrictSearchWithMatch: {
status: "enabled"
}
}
},
{
"$unwind": "$spreadChildren"
},
{
$sort: {
"spreadChildren.version": -1
}
},
{
$group: {
_id: {
_id: "$_id",
name: "$spreadChildren.name"
},
children: {
$first: "$children"
},
name: {
$first: "$name"
},
spreadChildren: {
$first: "$spreadChildren"
},
status: {
$first: "$status"
},
version: {
$first: "$version"
}
}
},
{
$group: {
_id: "$_id._id",
children: {
$first: "$children"
},
name: {
$first: "$name"
},
spreadChildren: {
$push: "$spreadChildren"
},
status: {
$first: "$status"
},
version: {
$first: "$version"
}
}
}
])
这里是Mongo playround供您参考。