Mongoengine聚合无法像mongo

时间:2019-12-30 06:45:30

标签: python python-3.x mongodb mongoengine

我有一个带有嵌入式文档列表的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)

我在做什么错了?

2 个答案:

答案 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)来查看问题是否有影响。