Как я могу получить данные профилей других пользователей в метеоре

У меня проблема с доступом к данным профиля пользователя других пользователей, а не текущего пользователя.

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

Запись в блоге идентифицируется по _id авторов, но дело в том, что я не могу получить доступ

Meteor.users.find({_id : authorId});

Результирующий курсор выглядит так же, как Meteor.user (не «пользователи»), состоит только из одного документа и действителен только для текущего идентификатора пользователя. Для других, таких как идентификатор авторов, я могу получить только пустую коллекцию.

Вопрос в том, есть ли какой-либо способ, кроме следующей подписки Meteor.users, чтобы получить профиль авторов (например, имя пользователя profile.nick и т. д.) ???


person Paul Paku    schedule 25.02.2016    source источник
comment
Meteor.users — это не что иное, как еще одна коллекция, поэтому вам нужно подписаться на нее, чтобы получать данные.   -  person Radu Chiriac    schedule 25.02.2016
comment
Ваш вопрос немного сбивает с толку. Вы хотите опубликовать все данные о пользователе на основе authorId или чего-то еще. По умолчанию только зарегистрированный пользователь публикуется для клиента в целях безопасности.   -  person Guns    schedule 25.02.2016
comment
Вроде так, поэтому и спрашиваю, есть ли какое-нибудь хитрое решение, кроме подписки.   -  person Paul Paku    schedule 25.02.2016


Ответы (2)


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

Meteor.publishComposite('blogEntries', function (blogEntryIds) {
    return [{
        find: function() {
            return BlogEntries.find({ courseId: { $in: blogEntryIds }});
            // you can also do -> return BlogEntries.find();
            // or -> return BlogEntries.find({ courseId: blogEntryId });
        },
        children: [{
            find: function(blogEntry) {
                return Meteor.users.find({ 
                    id: blogEntry.authorId 
                }, { 
                   fields: { 
                        "profile": 1,
                        "emails": 1
                   } 
                });
            }
        }}
    }]
});

Конец обновления

Вам нужно опубликовать Meteor.users с сервера, чтобы иметь возможность использовать его на клиенте. Пакет accounts опубликует текущего пользователя, поэтому вы видите только информацию о текущем пользователе.

В файле в папке сервера или в блоке Meteor.isServer if сделайте что-то вроде этого

//authorIds = ["authorId1", "authorId2];
Meteor.publish('authors', function (authorIds) {
    return Meteor.users.find({ _id : { $in: authorIds }});
});

or

Meteor.publish('author', function (authorId) {
    return Meteor.users.find({ _id : authorId });
});

Затем на стороне клиента подпишитесь на эту публикацию в функции onCreated шаблона примерно так:

Meteor.subscribe('author', authorId); //or Meteor.subscribe('author', authorIds);

or

template.subscribe('author', authorId); //or template.subscribe('author', authorIds);
person Kishor    schedule 25.02.2016
comment
Это рабочее решение, но я спросил, есть ли у меня какой-либо другой способ получения сведений о пользователе, кроме следующей подписки. - person Paul Paku; 25.02.2016
comment
Нет. Если вы удалите autopublish, это единственный способ реактивного получения пользовательских данных. Если вам нужна одна публикация для записей блога и пользователей, вы можете использовать пакет publish-composite. См. мой другой ответ здесь: stackoverflow.com/questions/35617821/ - person Kishor; 25.02.2016
comment
Как Meteor.publishComposite влияет на нагрузку сервера? - person Paul Paku; 25.02.2016
comment
Я обнаружил, что публикация композита выполняется довольно быстро. Однако очень важно: вам нужно ограничить поля, которые вы возвращаете для других пользователей. Например, {fields: {username: 1}}, иначе приведенный выше код @Kishor вернет все об этих пользователях, включая адреса электронной почты, зашифрованный пароль и т. д. - person Michel Floyd; 25.02.2016
comment
Запустили. Спасибо за ваше время, ребята. Есть только одно неприятное чувство, как вернуться к реляционной БД с использованием Mongo :) - person Paul Paku; 25.02.2016
comment
@Kishor Пожалуйста, добавьте фильтр для соответствующих полей в свой ответ. Приведенный выше код публикует хешированные пароли запрошенных пользователей. - person David Weldon; 25.02.2016
comment
@PaulPaku: publishComposite будет медленнее по сравнению с обычной публикацией, потому что запросы в children будут выполняться один раз для каждой записи, найденной в запросе find. Для небольших наборов данных это должно быть в порядке. Для больших наборов данных вы можете использовать денормализацию, как в другом упомянутом ответе. Вы также можете ограничить поля, как и другие комментаторы, упомянутые выше. Вы также должны следовать хорошим стратегиям индексации, чтобы сократить время. Я обновил ответ, чтобы ограничить коллекцию user только публикацией profile и emails, чтобы прекратить отправку паролей на сторону клиента. - person Kishor; 26.02.2016
comment
@MichelFloyd: Вы правы. Я должен был сделать это изначально, вместо этого я просто сосредоточился на соединениях. Спасибо, что указали на это. :) - person Kishor; 26.02.2016
comment
@DavidWeldon: Вы правы. Я должен был сделать это изначально, вместо этого я просто сосредоточился на соединениях. Спасибо, что указали на это. :) - person Kishor; 26.02.2016

Если вы хотите показать только имя пользователя (или несколько других полей), вы можете сохранить их в почтовом документе вместе с authorId. Например:

post:{
   ...
   authorId: someValue,
   authorName: someValue
} 

Вы можете использовать их в своих шаблонах в качестве поля поста. Если у вас слишком много полей, которые вы не хотите вставлять в почтовый документ (поэтому вы хотите оставить только authorId), вы можете использовать publish-composite, когда вы публикуете свои сообщения. (см. пример 1)

Вам не нужно публиковать всех ваших пользователей и их профили.

person Areca    schedule 25.02.2016
comment
Хорошая идея, но потребуется больше места для хранения. Может быть решением, если я забуду свой родственный фон :) - person Paul Paku; 25.02.2016
comment
Отметил ответ @Kishor, так как я думаю, что это популярное решение, но мое личное мнение таково, что ваша идея более готова к Монго. - person Paul Paku; 25.02.2016
comment
@PaulPaku, этот процесс известен как денормализация, вы можете найти дополнительную информацию о том, когда и когда этого не следует делать здесь blog.mongodb.org/post/88473035333/. В большинстве случаев меньше expensive для денормализации связано с тем, что вам придется совершать меньше обращений к базе данных, чтобы вернуть нужные данные. Кроме того, не выполняя соединение на стороне сервера, вы будете использовать меньше циклов ЦП. Это всего лишь несколько вещей, о которых следует помнить при использовании mongo. Статья расскажет более подробно. Удачи! - person Patrick Mencias-lewis; 26.02.2016
comment
@PatrickMencias-lewis Вы правы. На данный момент, похоже, мы будем использовать денормализованную модель Mongo без отношений. - person Paul Paku; 26.02.2016
comment
@PaulPaku, вы также должны изучить метеор до и после крючков. При этом вы можете проверить, изменил ли пользователь свое имя, и если это так, выполните массовое обновление коллекции, чтобы обновить имена. Сейчас это дорого, но редко бывает. - person Patrick Mencias-lewis; 26.02.2016