Mongoengine查询从集合中的同一文档的数组返回匹配元素

时间:2014-05-31 23:14:19

标签: django mongodb aggregation-framework mongoengine

mongoengine查询只返回以" B"开头的位置名称。来自下面的馆藏文件?

{ 
    "_id" : ObjectId("5388ae8df30090186310ed77"), 
    "city" : "Pune", 
    "locations" : [ 
        "Kalyani Nagar", 
        "Vishrantwadi", 
        "Camp", 
        "Bhawani Peth", 
        "Kasarwadi", 
        "Deccan Gymkhana",
        "Dhankawadi", 
        "Wanowrie", 
        "Sinhagad Road-Vadgaon Budruk", 
        "Kothrud", 
        "Pune Cantonment", 
        "Bibvewadi", 
        "Shivaji Nagar", 
        "Pimple Nilakh-Pimpri Chinchwad",
        "Thergaon", 
        "Dapodi", 
        "Wakad", 
        "Katraj", 
        "Pashan Gaon"
    ]
}

Collection.objects(locations _istartswith =" B",city__iexact =" Pune")。distinct(" locations")

没有给出预期的结果。

1 个答案:

答案 0 :(得分:1)

你基本上需要的是MongoDB中的aggregation framework方法,因为你的条件存在“多个”匹配,这不能通过简单的查询投影来解决。考虑到可能符合条件的多个文档,基本陈述是这样的:

db.collection.aggregate([
    // Match only the documents that satisfy the condition
    { "$match": {
        "city": "Pune",            
        "locations": { "$regex": "^B" }
    }},

    // Unwind the array as individual documents
    { "$unwind": "$locations" },

    // Match to "filter" the array elements
    { "$match": {
        "locations": { "$regex": "^B" }
    }},

    // Group back to documents if required
    { "$group": {
        "_id": "$_id",
        "city": { "$first": "$city" },
        "locations": { "$push": "$locations" }
    }}

因此$regex匹配以“B”开头的“locations”的值会进行所需的过滤工作。首先只匹配集合中符合条件的文档,然后在那些匹配文档中的数组的$uwnind之后再次使用它来“过滤”实际的数组条目。

然后,您可以使用$group将所有内容作为文档放回到响应中仅包含匹配的数组元素。因此,对于您的文档,结果将是:

{ 
    "_id" : ObjectId("5388ae8df30090186310ed77"), 
    "city" : "Pune", 
    "locations" : [ 
        "Bhawani Peth", 
        "Bibvewadi", 
    ]
}

请注意,$regex可以修改为您需要的任何内容或不区分大小写,但最有效的形式将是“开头”,如图所示。所以尽可能使用它。

这将要求您访问MongoEngine底层的原始“pymongo”驱动程序,以获取该基本“集合”对象并使用聚合方法。由于来源不同,我不能完全确定正确的方法,但是link可能会对这一部分有所帮助。