0
votes

I'm trying to figure out how to do this in a Meteor Publish for my Posts collection:

  1. Check if the sharedBy array contains the current userId.
    • sharedBy is an array of all the users that shared this post.
  2. If so, update the Posts collection with a boolean i.e. isSharedCurrentUser to 1.
    • preferably only the client collection gets this new field added.
  3. Publish the Posts collection but EXCLUDE the sharedBy array (since it could contain millions of entries).
2
I'd like to know a little more about this publish function: Does it take arguments? Does it publish all posts or just those for the current user? Are there other post-publishing functions? etc.David Weldon
Could you explain what you are using number 2 for as it seems like it could be the wrong way to go about this, and would make everything much prettier if we came up with another way to achieve it.1321941
I want to check if the current logged in user shared the post that gets shown during the Handlebars {{#each posts}}. The Publish function I had in mind doesn't take any arguments.Giant Elk

2 Answers

1
votes

If your sharedBy array could have millions of entries, I suggest switching the way you track 'shared'. Add an array, sharedPostIds, to the user object which contains a list of all of the posts the user has shared.

To compare numbers, if a power-user shares 10 posts a day, that would be 3650 entries / year. Probably not enough to notice when sending down to the client.

If you need to ensure that data isn't sent to the client, you can make a Meteor method that does batched lookups asynchronously.

1
votes

Here's a solution I have working, from Gadi: https://plus.google.com/u/0/107554020054962631548/posts

This appears to be a really bad idea for large #'s of shares i.e. over a few thousand, since Mongo has a maximum document size of 16Meg, so I figure with 100K users in the SharedBy array it will cause major performance issues. I'm going to work on getting it to work with references VS embedded way, as per this post: Meteor, One to Many Relationship & add field only to client side collection in Publish?

Below works, but will not be efficient due to the growing array of SharedBy users:

// includes a sharedBy: [userId1, userId2, etc...] field.
Posts = new Meteor.Collection('posts');

Meteor.publish('posts', function() {

    var self = this;
    var handle = Posts.find().observeChanges({
        added: function(id, fields) {
            fields.sharedByMe = _.contains(fields.sharedBy, self.userId);
            delete(fields.sharedBy);
            self.added('posts', id, fields);
        },
        changed: function(id, fields) {
            if (fields.sharedBy) {
                fields.sharedByMe = _.contains(fields.sharedBy, self.userId);
                delete(fields.sharedBy);
            }
            self.changed('posts', id, fields);
        },
        removed: function(id) {
            self.removed('posts', id);
        },
    });

    // Stop observing cursor when client unsubscribes
    self.onStop(function() {
            handle.stop();
    });

    self.ready();

});