5

我正在寻找在 python 中创建和处理游标的方式,就像游标在 mongo 中本机工作的方式一样。我知道预期的方法是执行“result = collection.find()”并执行“for record in result”,但我希望将迭代功能包装在一个类中。我希望能够创建一个新的类对象并调用一个函数,例如 init_cursor() 来建立一个数据库连接并执行一个返回游标的查找。然后我希望有一个 get_next() 函数,该函数将移动到下一个结果并根据结果设置类数据成员。这是伪代码:

class dataIter():
    def __init__(self):
        self.collection = pymongo.Connection().db.collection
        self.cursor = self.collection.find({}) #return all
        self.age = None
        self.gender = None

    def get_next(self):
        if self.cursor.hasNext():
            data = self.cursor.next()
            self.set_data(data)

    def set_data(self, data):
        self.age = data['age']
        self.gender = data['gender']

这样我就可以简单地调用:

obj.get_next()
age = obj.age
gender = obj.gender

或其他一些帮助功能,用于从每个文档中提取数据

4

4 回答 4

18

我不明白您所展示的内容比仅执行以下操作更方便:

col = pymongo.Connection().db.collection
cur = col.find({})

obj = next(cur, None)
if obj:
    age = obj['age']
    gender = obj['gender']

目前尚不清楚这个包装器有什么帮助。此外,如果你真正追求的是 ORM,那么当它存在时不要重新发明轮子:http: //mongoengine.org/

于 2012-05-03T02:06:04.853 回答
1

你应该使用python迭代器协议,你的类可以看起来像这样

class DataIter:
    def __init__(self):
         self.collection = pymongo.Connection().db.collection
         self.cursor = self.collection.find({}) #return all
         self.age = None
         self.gender = None
    def __iter__(self):
         return self
    def next(self):
        if self.cursor.hasNext():
            data = self.cursor.next()
            self.set_data(data)
            return self
        else:
            raise StopIteration

然后你可以像这样迭代

for c in DataIter():
    age = c.age
    gender = c.gender
于 2012-05-03T02:41:25.197 回答
1

Here's what I ended up going with:

class Cursor(object):

    def __init__(self):
        # mongo connection
        self.collection = pymongo.Connection().cursorcollection
        self.loaded = False
        self.cursor = None

    # Cursor calls (for iterating through results)
    def init_cursor(self):
        """ Opens a new cursor """
        if not self.cursor:
            self.cursor = self.collection.find({})

    def get_next(self):
        """ load next object """
        if self.cursor and self.cursor.alive:
            self.set_data(next(self.cursor))
            return True
        else:
            self.cursor = None
            return False

    def has_next(self):
        """ cursor alive? """
        if self.cursor and self.cursor.alive:                                                                                                                                                                                                                                
            return True
        else:
            return False
于 2012-05-07T18:58:26.553 回答
1

您可以使用类似于您已经发布的内容来完成此操作。PyMongo 游标没有haveNext方法,但它们有一个next方法可以返回下一个文档,或者 raise StopIteration(这是由 Python 迭代器协议指定的)。

您还可以更进一步:您可以使用__getattr__which 实现 Python 类的属性查找,而不是将文档中的值分配给类的属性。

把它们放在一起,你最终可能会得到类似的东西:

class DataIter(object):

    def __init__(self, cursor):
        self._cursor = cursor
        self._doc = None

    def next(self):
        try:
            self._doc = self._cursor.next()
        except StopIteration:
            self._doc = None
        return self

    def __getattr__(self, key):
        try:
            return self._doc[key]
        except KeyError:
            raise AttributeError('document has no attribute %r' % name)
于 2012-05-03T15:19:27.650 回答