0

我正在尝试在 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()
4

1 回答 1

3

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

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

如果您寻找连接、map reduce、mongodb 等,您会在 Internet 上找到许多建议。他们会将多步 map reduce 放入同一个集合中。这并不简单,也不一定有效。

从您的代码来看,您似乎只是想快速查找产品名称。您可以通过多种方式对其进行优化,而无需加入。我建议在本地缓存名称,当这不起作用时,使用$in运算符收集一组产品,并通过投影将结果限制为您需要的最小字段(例如name),并缓存这些结果。 .. 然后在 Python 中的客户端上执行“本地”连接(name如果需要,您可以在其中获取值并将其作为“虚拟”属性输出) .

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

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

于 2013-09-19T14:49:41.130 回答