我有一个对象的光标,我正在尝试Paginate。我想要的总项目是25,但是与Django的分页方式一样,它需要整个光标。在私人测试中,大概是因为我的家用盒子有更多RAM等,我没有这些问题。但是,当推送到只有2GB内存的生产机器时,我得到一个MemoryError,可能是因为光标太大了。
我可以使用.limit(25)和.skip()来一次只检索25个东西,但是为了让Pagination工作,我需要对象的总数。不幸的是,.count()似乎需要获取光标的整个数据。理想情况下,如果我能够以某种方式获得查找的大小并且只有25个实际对象在游标之外,我可以使这个工作。
所以我想问题是,有没有办法让光标的大小不通过.count()(它获取整个光标的数据)。
lookup = players.find({field: {'$exists': True}}).sort(field, DESCENDING)
//This returns a MemoryError
lookup = players.find({field: {'$exists': True}}).limit(25).skip(25).sort(field, DESCENDING)
//This does NOT return a Memory Error. However, when I do the following:
lookup.count()
//This also has a MemoryError.
为了澄清,我使用的是Django 1.5.11和pymongo 3.2.1。
答案 0 :(得分:1)
通常建议使用range queries,而不是使用skip()
和limit()
进行分页。这是因为:
skip()
和limit()
必须迭代光标并丢弃结果,这意味着你会做很多不必要的工作。skip()
和limit()
。例如,您可以使用一系列密钥代替skip()
和limit()
。以id
字段为例,假设id
字段的数字不断增加:
db.collection.find({id: {$gte: 0, $lt: 25}, field: {'$exists': True}})
然后,您可以创建id:1, field:1
db.collection.createIndex({id:1, field:1})
,例如:
typedef struct {
node *head;
size_t size;
} stack_t;
size_t stack_size(stack_t *stack) {
return stack->size;
}
bool is_empty(stack_t *stack) {
return stack_size(stack) == 0;
}
stack_t *stack_create(void) {
stack_t *stack = malloc(sizeof(stack_t));
stack->size = 0;
stack->head = NULL;
return stack;
}
void push(stack_t *stack, int data) {
node *new_node = malloc(sizeof(struct nodeRec));
new_node->item = data;
new_node->next = stack->head;
stack->head = new_node;
stack->size++;
}
int pop(stack_t *stack) {
assert(!is_empty(stack));
node *old_head = stack->head;
stack->head = stack->head->next;
int ret = old_head->item;
free(old_head);
stack->size--;
return ret;
}
这将使索引支持分页,因此无需进行任何不必要的工作即可快速高效。