我正在寻找在游标中创建和处理游标的方式,就像游标本身在mongo中工作一样。我知道预期的方法是执行'result = collection.find()'并执行'for result in result',但我希望将迭代功能包装在一个类中。我希望能够创建一个新的类对象并调用一个函数,例如init_cursor()建立数据库连接并执行返回游标的查找。然后我想有一个get_next()函数,它将移动到下一个结果并根据结果设置类数据成员。这是pesudo代码:
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
或其他一些帮助函数从每个文档中提取数据
答案 0 :(得分:14)
我不明白你所展示的内容如何更方便:
col = pymongo.Connection().db.collection
cur = col.find({})
obj = next(cur, None)
if obj:
age = obj['age']
gender = obj['gender']
不清楚这个包装器是如何有用的。此外,如果您真正关注的是ORM,那么在存在时不要重新发明轮子:http://mongoengine.org/
答案 1 :(得分: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
答案 2 :(得分:1)
您可以使用已经发布的内容来完成此操作。 PyMongo游标没有haveNext
方法,但它们有next
方法,它将返回下一个文档,或者引发StopIteration
(这是由Python迭代器协议指定的)。
您还可以更进一步:不是将文档中的值分配给类的属性,而是使用__getattr__
实现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)
答案 3 :(得分:1)
这就是我最终的目标:
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