我有一个带有嵌入式文档列表的Mongo文档(下面的示例)。我正在尝试进行汇总,以返回列表中仅包含匹配对象的完整文档。
示例收集数据
{
"make": "Toyota",
"color": "blue",
"tires": [{
"make": "Mishlen",
"size": 185
}, {
"make": "Mishlen",
"size": 210
}]
}
通过以下查询,我设法使其在MongoDB中工作
db.cars.aggregate(
[
{
$match: {$and: [{"tires.size": {$gt: 200}}]}
},
{
$addFields: {
"tires": {
$filter: {
input: '$tires',
as: 'tires',
cond: {$gt: ['$$tires.size', 200]}
}
}
}
},
{
$limit: 100
},
{
$skip: 0
}
])
我正在尝试在mongoengine中运行相同的聚合,并且每次都返回一个空列表。
pipeline = [
{
"$match": {"$and": [{"tires.size": {"$gt": 200}}]}
},
{
"$addFields": {
"tires": {
"$filter": {
"input": "$tires",
"as": "tires",
"cond": {"$and": [{"$gt": ["$$tires.size", 200]}]}
}
}
}
}
]
self.obj_type.objects.aggregate(*pipeline)
我在做什么错了?
答案 0 :(得分:1)
以下工作流程将是最简单的
pipeline = [
{
$unwind: "$tires"
},
{
"$match": {"$and": [{"tires.size": {"$gt": 200}}]}
},
{
$group : {
_id : "$make",
tires: { $push: "$tires" }
}
}
]
self.obj_type.objects.aggregate(*pipeline)
答案 1 :(得分:0)
在插入您提供的示例文档之后,使用您提供的管道运行聚合没有任何特殊问题。见下文:
class Tire(EmbeddedDocument):
make = StringField()
size = IntField()
class Car(Document):
make = StringField()
color = StringField()
tires = EmbeddedDocumentListField(Tire)
meta = {'collection': 'cars'}
pipeline = [
{
"$match": {"$and": [{"tires.size": {"$gt": 200}}]}
},
{
"$addFields": {
"tires": {
"$filter": {
"input": "$tires",
"as": "tires",
"cond": {"$and": [{"$gt": ["$$tires.size", 200]}]}
}
}
}
}
]
# Verify aggregation pipeline runs fine with the driver (pymongo)
coll = Car._get_collection()
pymongo_result = list(coll.aggregate(pipeline))
assert len(pymongo_result) == 1
# Run same aggregation pipeline with MongoEngine
mongoengine_result = list(Car.objects.aggregate(*pipeline))
assert len(mongoengine_result) == 1
result = [
{'_id': ObjectId('5e0a5c8e7c57cd9b300710fb'),
'color': 'blue',
'make': 'Toyota',
'tires': [{'make': 'Mishlen', 'size': 210.0}]
}
]
assert mongoengine_result == pymongo_result == result
我使用了最新的mongoengine版本,但AFAIK最近对MongoEngine的聚合包装没有重大更改。问题可能出在您的self.obj_type.objects
端,请像我一样尝试使用新的查询集(即YourDocumentClass.objects
)来查看问题是否有影响。