如何在PyMongo中执行等效的SQL Join?或更具体的用BSON代码调用Pymongo集合对象? [英] How do I perform the SQL Join equivalent in PyMongo? Or more specific call a Pymongo collection object in BSON code?

查看:320
本文介绍了如何在PyMongo中执行等效的SQL Join?或更具体的用BSON代码调用Pymongo集合对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to perform a SQL Join equivalent in pymongo like so: http://blog.knoldus.com/2013/02/03/joins-now-possible-in-mongodb/

问题是,我陷入困境,因为bson无法编码集合对象.

The thing is, I am stuck as bson cannot encode collection objects.

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()

推荐答案

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

While I'm not sure of your schema, you can't pass a local Python reference to a MongoDB collection to the Code object and have it be available on the Database server. You could pass a scope object, but here, that's not what you need. Ultimately, the code is just Javascript, so it needs to access the Products collection locally/natively.

但是,我刚被提醒,从2.4+开始,不再可以从MapReduce访问其他集合/数据库/碎片.因此,您将无法访问相同集合或不同集合中的任何其他文档,也无法访问来自地图或约简功能的其他文档.

However, I was just reminded, that as of 2.4+, it's no longer possible to access other collections/databases/shards from a MapReduce. So, you can't access other documents, either in the same collection or a different collection or from either the map or reduce functions.

如果您查找联接,map reduce,mongodb等,您会在Internet上找到许多建议.他们会在同一集合中进行多步map reduce.这并不简单,也不一定有效.

There are a number of suggestions that you'll find on the internet if you look for joins, map reduce, mongodb, etc. They'll do multiple step map reduces into the same collections. It's not simple, nor necessarily efficient.

从您的代码中,您似乎只是想快速查找产品名称.您可能有多种方法可以在不需要联接的情况下对其进行优化.我建议在本地缓存名称,当这不起作用时,使用$in运算符收集一组产品,并进行投影以将结果限制为所需的最小字段(例如name) ,并缓存这些结果...然后在Python客户端上进行本地"连接(在其中,您可以获取name值,并将其输出为虚拟"类属性,如果需要交付类或其他地方)否则就被客户消耗掉了.)

From your code, it looks like you're just trying to do a quick lookup of Product names. There are a number of ways you might be able to optimize that without needing a join. I'd suggest caching the names locally, and when that doesn't work, using the $in operator to gather a set of products, with a projection to limit the results to the minimum fields you need (such as name), and cache those results ... and then do a "local" join on the client in Python (in which you grab the name value and output it as a "virtual" like property if needed with your Delivery class, or somewhere else downstream as it's consumed by a client).

由于MongoDB有意不支持Joins,因此通常最好考虑您的集合和文档结构是否最适合您所需的模式.

As MongoDB intentionally does not support Joins, it's usually best to consider whether your collection and document structures are best designed for the patterns you need.

您还可以只在MongoDB控制台中创建地图缩小功能.

这篇关于如何在PyMongo中执行等效的SQL Join?或更具体的用BSON代码调用Pymongo集合对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆