Запрос от minimongo большого количества записей stucks и зависает браузера

Я создаю страницу для администратора в angular -meteor.

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

$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:

Хорошо! Он отлично работал, когда я прокомментировал строку $sort из запроса следующим образом:

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

            return Posts.find(

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

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

EDIT:

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

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

Еще одна проблема.

Ответ 1

Измените публикацию, чтобы принять параметр с именем 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
   });
});

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

Если он использует стандартный шаблон blaze, я бы сделал это, используя реактивный 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, как указано в официальной документации здесь

// 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

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

Ответ 4

Вам нужно рассмотреть стратегии сортировки и ограничения:

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

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

Ответ 5

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

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