10

Я строю страницу для администратора в angular-meteor.Запрос от minimongo большого количества записей stucks и зависает браузера

У меня есть опубликованные все записи из коллекции: «сообщения» и взяли подписку всех записей на переднем конце.

$meteor.subscribe('posts'); 

В контроллере, если выбрать курсоры всех записей из minimongo он прекрасно работает как:

$scope.posts = $meteor.collection(Posts); 

Но я хочу, чтобы отобразить нумерацию страниц, поэтому для этого я хочу, ограниченные записи в то время, подобный:

$scope.posts = $meteor.collection(function(){ 

     return Posts.find(

      {}, 
      { 
       sort: {'cDate.timestamp': -1}, 
       limit: 10 
      } 
     ); 
    }); 

Он разбирается с запросом в minimongo. И браузер зависает.

«сообщений» коллекция содержит всего 500 записей. Он работал нормально, когда у меня было 200 записей.

Может ли кто-нибудь дать мне представление о том, что случилось с моим кодом и понятиями?

EDIT:

Хорошо! Он работал хорошо, когда я прокомментировал $ сортировать строку из запроса, как это:

$scope.posts = $meteor.collection(function(){ 

      return Posts.find(

       {}, 
       { 
        //sort: {'cDate.timestamp': -1}, 
        limit: 10 
       } 
      ); 
     }); 

Но мне нужно отсортировать записи. Итак, что мне теперь делать?

EDIT:

также попытался добавить индекс атрибута сортировки, как это:

db.Posts.ensureIndex({"cDate.timestamp": 1}) 

Тем не менее такой же вопрос.

+0

Вы пытались добавить индекс в поле cDate.timestamp. Добавьте индекс, упомянутый в этом сообщении, http://stackoverflow.com/questions/9730136/how-to-create-a-nested-index-in-mongodb 'db.Posts.ensureIndex ({" cDate.timestamp ": 1 }) ' – Kishor

+0

Хорошо, позвольте мне попробовать это – StormTrooper

+0

Попробовал добавить индекс. Не работает. Тот же вопрос. Браузер застрял – StormTrooper

ответ

2

Браузер сбоев, потому что есть только так много данных, которые он может загружать в свой кеш, прежде чем обналичивать. На ваш вопрос о том, что происходит, когда вам нужно потребовать большое количество документов, отвлеките этот процесс от клиента и сделайте столько на сервере, используя оптимизированные методы публикации и подписки. Нет реальной причины загружать тонну документов в кеш браузера, поскольку удобство minimongo - для небольших наборов данных и вещей, которые не требуют немедленной синхронизации (или синхронизации) с сервером.

+0

Ок, скажите мне, как я покажу разбивку на страницы на клиенте? Как я покажу реактивный счетчик всех записей? Или как я могу применить фильтры, которые будут искать из полной базы данных? – StormTrooper

+0

Это очень возможно. Сначала определите, как вы собираетесь подписываться на сообщения в первом случае. Похоже, вы уходите от minimongo (что определенно соответствует лучшим методам Meteor). –

+0

Итак, если вы собираетесь использовать сервер/клиентскую коллекцию: подписываетесь ли вы на уровне шаблона или на уровне маршрутизатора? Какой маршрутизатор вы будете использовать? Вы публикуете все свои документы и затем фильтруете подписку? Перед тем, как попасть в разбивку на страницы, нужно сначала их обработать. Некоторым людям нравится делать код для вас здесь. Я хочу посмотреть, можете ли вы предоставить нам некоторые фрагменты того, где вы находитесь. Если вам нужна помощь в вышеупомянутых концепциях, это еще одна история, но я думаю, вы можете это сделать! –

2

Вы должны рассмотреть рода и предельные стратегии:

Сортировка на сервере, если вы извлечение верхних значений из большого набора, используемого всеми клиентами. Но обычно лучше сначала фильтровать пользователь, которому нужны данные, и сортировать по фильтрованной коллекции. Это уменьшит набор данных.

Затем опубликуйте это отсортированное/ограниченное подмножество для клиента, и вы можете сделать более мелкозернистую/сортировочную фильтрацию.

3

Измените публикацию, чтобы принять параметр, называемый pageNumber как этого

Meteor.publish('posts', function (pageNumber) { 
    var numberOfRecordsPerPage = 10; 
    var skipRecords = numberOfRecordsPerPage * (pageNumber - 1); 
    return Post.find({ 
     "user_id": user_id 
    }, { 
     sort: { 'cDate.timestamp': -1 } 
     skip: skipRecords, 
     limit: numberOfRecordsPerPage 
    }); 
}); 

На стороне клиента, я не работал с угловым-метеором много. Вы можете создать свойство pageNumber под своей текущей областью действия, используя this.pageNumber или $scope.pageNumber. Обновите эту переменную pageNumber всякий раз, когда нажимается страница с разбивкой по страницам. Всякий раз, когда эта переменная изменяется, подпишитесь с использованием текущего номера страницы.

Если он использует стандартный шаблон пламени, я бы сделал это, используя реактивную переменную var или session var в autorun, как это. В шаблоне HTML:

<template name="postsTemplate"> 
    <ul> 
     <!-- you would want to do this list based on total number of records --> 
     <li class="pagination" data-value="1">1</li> 
     <li class="pagination" data-value="2">2</li> 
     <li class="pagination" data-value="3">3</li> 
    </ul> 
</template> 

В шаблоне JS:

Template.postsTemplate.created = function() { 
    var template = this; 
    Session.setDefault('paginationPage', 1); 
    template.autorun(function() { 
     var pageNumber = Session.get('paginationPage'); 
     Meteor.subscribe('posts', pageNumber); 
    }); 
} 

Template.postsTemplate.events(function() { 
    'click .pagination': function (ev, template) { 
     var target = $(ev.target); 
     var pageNumber = target.attr('data-value'); 
     Session.set('paginationPage', pageNumber); 
    } 
}); 

Таким образом, вы будете иметь максимум 10 записей в любой момент времени на клиенте, так что это не приведет к краху браузера , Вы также можете ограничить поля, которые вы отправляете клиенту, используя что-то вроде этого

Meteor.publish('posts', function (pageNumber) { 
    var numberOfRecordsPerPage = 10; 
    var skipRecords = numberOfRecordsPerPage * (pageNumber - 1); 
    return Post.find({ 
     "user_id": user_id 
    }, { 
     sort: { 'cDate.timestamp': -1 } 
     skip: skipRecords, 
     limit: numberOfRecordsPerPage, 
     fields: {'message': 1, 'createdBy': 1, 'createdDate': 1 } //The properties inside each document of the posts collection. 
    }); 
}); 

И, наконец, вам нужно общее количество записей в коллекции сообщений на стороне клиента, чтобы показать ссылки разбивки на страницы. Вы можете сделать это с помощью другого издания и используя observeChanges понятие, как указано в официальной документации here

// server: publish the current size of a collection 
Meteor.publish("posts-count", function() { 
    var self = this; 
    var count = 0; 
    var initializing = true; 

    // observeChanges only returns after the initial `added` callbacks 
    // have run. Until then, we don't want to send a lot of 
    // `self.changed()` messages - hence tracking the 
    // `initializing` state. 
    var handle = Posts.find({}).observeChanges({ 
    added: function (id) { 
     count++; 
     if (!initializing) 
     self.changed("postsCount", 1, {count: count}); 
    }, 
    removed: function (id) { 
     count--; 
     self.changed("postsCount", 1, {count: count}); 
    } 
    // don't care about changed 
    }); 

    // Instead, we'll send one `self.added()` message right after 
    // observeChanges has returned, and mark the subscription as 
    // ready. 
    initializing = false; 
    self.added("postsCount", 1, {count: count}); 
    self.ready(); 

    // Stop observing the cursor when client unsubs. 
    // Stopping a subscription automatically takes 
    // care of sending the client any removed messages. 
    self.onStop(function() { 
    handle.stop(); 
    }); 
}); 

// client: declare collection to hold count object 
PostsCount = new Mongo.Collection("postsCount"); 

// to get the total number of records and total number of pages 
var doc = PostsCount.findOne(); //since we only publish one record with "d == 1", we don't need use query selectors 
var count = 0, totalPages = 0; 

if (doc) { 
    count = doc.count; 
    totalPages = Math.ceil(count/10); //since page number cannot be floating point numbers.. 
} 

Надежда это помогает.

2

Вы должны использовать ограничение на стороне сервера вместо клиентской стороны. Это сделает ваше приложение быстрее и оптимизировано.

Для получения дополнительной информации, пожалуйста, проверьте эту ссылку. link here