如何在PyMongo中执行SQL Join等效操作?或者更具体的是在BSON代码中调用Pymongo集合对象?

时间:2013-09-19 14:14:04

标签: python mongodb join pymongo bson

我正在尝试在pymongo中执行SQL Join等效操作,如下所示: http://blog.knoldus.com/2013/02/03/joins-now-possible-in-mongodb/

问题是,我被卡住了,因为bson无法编码集合对象。

bson.errors.InvalidDocument: Cannot encode object: Collection(Database(MongoClient('localhost', 27017), 'Application'), 'Products')

所有相关代码:

class Delivery(Repository):

    COLLECTION_ATTRIBUTE = 'deliveriesCollection'

    def __init__(self):
        Repository.__init__(self, self.COLLECTION_ATTRIBUTE)

    def printTable(self):
        from bson.code import Code

        mapper = Code('function() {'
                    '    product = ProductCollection.findOne({_id:this.Product_ID});'
                    '    data = {'
                    '        \'Name\':this.Name,'
                    '        \'Product_ID\': product.ID'
                    '    };'  
                    '    emit(this._id, data );'
                    '}', ProductCollection = product.collection)

        reducer = Code('function(key, values) {'
                    '    return values[0];'
                    '}')

        result = self.collection.map_reduce(mapper, reducer, "myresults")

        for doc in result.find():
            print(doc)

delivery = Delivery()
product = Product()

1 个答案:

答案 0 :(得分:3)

虽然我不确定您的架构,但您无法将对MongoDB集合的本地Python引用传递给Code对象,并使其在数据库服务器上可用。你可以传递一个范围对象,但在这里,这不是你需要的。最终,代码只是Javascript,因此需要本地/本地访问Products集合。

但是,我刚才提醒,从2.4+开始,不再可能从MapReduce访问其他集合/数据库/分片。因此,您无法访问同一集合或不同集合中的其他文档,也无法访问map或reduce函数。

如果您要查找联接,地图缩小,mongodb等,您可以在互联网上找到许多建议。他们会将多步骤地图缩减为相同的集合。这不简单,也不一定有效。

从您的代码中,您似乎只是想快速查找产品名称。有许多方法可以在不需要连接的情况下优化它。我建议在本地缓存这些名称,当这不起作用时,使用$in运算符来收集一组产品,并使用投影将结果限制为您需要的最小字段(例如{{ 1}}),并缓存这些结果......然后在Python中在客户端上执行“本地”连接(在其中您获取name值并将其输出为“虚拟”类似属性(如果需要)您的Delivery类,或者客户端使用的其他下游的其他地方。

由于MongoDB故意不支持联接,因此通常最好考虑您的收藏和文档结构是否最适合您所需的模式。

你也可以在MongoDB控制台中创建map reduce函数。