MongoDB 按结果限制分组
MongoDB limit group by results
我的 mongo 数据库有一个结构如下的文档:
{'vname':'x', 'pname': 'xyz', 'price': '10000'}
我想获取所有匹配 pname='xy'
的文档,然后按 vname
分组并将每个 vname
的结果限制为 4.
pipeline = [
{
'$facet': {
'v1': [
{
'$match': {'vname': 'v1'}
},
{
'$sort': {'price': 1}
},
{
'$limit': 4
}
],
'v2': [
{
'$match': {'vname': 'v2'}
},
{
'$sort': {'price': 1}
},
{
'$limit': 4
}
]
}
}
]
docs = Pinfo.objects(pname__icontains='xy').aggregate(pipeline=pipeline)
我看到的另一种方法是 运行 过滤器查询多次 vname
docs = Pinfo.objects.filter(Q(pname__icontains='xy')&Q(vname__exact='v1')).limit(4)
还有其他方法可以达到同样的效果吗?
使用聚合和管道方法是否更好?
你可以试试,
$match
pname
条件
$sort
按 pname
升序排列(可选)
$group
by vname
并将根对象推入项目并制作数组
$project
显示必填字段并使用 $slice
获取 4 个对象
db.collection.aggregate([
{ $match: { pname: "xy" } },
{ $sort: { pname: 1 } },
{
$group: {
_id: "$vname",
items: { $push: "$$ROOT" }
}
},
{
$project: {
_id: 0,
vname: "$_id",
items: { $slice: ["$items", 4] }
}
}
])
如果你想要根目录中的所有对象,那么你可以在上面的管道之后添加下面的管道,
$unwind
将项目数组解构为对象
$replaceRoot
替换根目录中的项目对象
{ $unwind: "$items" },
{ $replaceRoot: { newRoot: "$items" } }
我的 mongo 数据库有一个结构如下的文档:
{'vname':'x', 'pname': 'xyz', 'price': '10000'}
我想获取所有匹配 pname='xy'
的文档,然后按 vname
分组并将每个 vname
的结果限制为 4.
pipeline = [
{
'$facet': {
'v1': [
{
'$match': {'vname': 'v1'}
},
{
'$sort': {'price': 1}
},
{
'$limit': 4
}
],
'v2': [
{
'$match': {'vname': 'v2'}
},
{
'$sort': {'price': 1}
},
{
'$limit': 4
}
]
}
}
]
docs = Pinfo.objects(pname__icontains='xy').aggregate(pipeline=pipeline)
我看到的另一种方法是 运行 过滤器查询多次 vname
docs = Pinfo.objects.filter(Q(pname__icontains='xy')&Q(vname__exact='v1')).limit(4)
还有其他方法可以达到同样的效果吗? 使用聚合和管道方法是否更好?
你可以试试,
$match
pname
条件$sort
按pname
升序排列(可选)$group
byvname
并将根对象推入项目并制作数组$project
显示必填字段并使用$slice
获取 4 个对象
db.collection.aggregate([
{ $match: { pname: "xy" } },
{ $sort: { pname: 1 } },
{
$group: {
_id: "$vname",
items: { $push: "$$ROOT" }
}
},
{
$project: {
_id: 0,
vname: "$_id",
items: { $slice: ["$items", 4] }
}
}
])
如果你想要根目录中的所有对象,那么你可以在上面的管道之后添加下面的管道,
$unwind
将项目数组解构为对象$replaceRoot
替换根目录中的项目对象
{ $unwind: "$items" },
{ $replaceRoot: { newRoot: "$items" } }