问题描述
我的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'}
},{
'$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
和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
替换root中的项目对象
{ $unwind: "$items" },{ $replaceRoot: { newRoot: "$items" } }