1

I need to publish a simplified version of posts to users. Each post includes a 'likes' array which includes all the users who liked/disliked that post, e.g:

[
    { 
        _id: user_who_liked, 
        liked: 1 // or -1 for disliked 
    }, 
    ..
]

I'm trying to send a simplified version to the user who subscribes an array which just includes his/her like(s):

Meteor.publish('posts', function (cat) {
  var _self = this;
  return Songs.find({ category: cat, postedAt: { $gte: Date.now() - 3600000 } }).forEach(function (post, index) {
    if (_self.userId === post.likes[index]._id) {
      // INCLUDE
    } else
      // REMOVE

    return post;
  })
});

I know I could change the structure, including the 'likes' data within each user, but the posts are usually designed to be short-lived, to it's better to keep that data within each post.

chridam
  • 100,957
  • 23
  • 236
  • 235
Mazka
  • 309
  • 1
  • 4
  • 14

1 Answers1

0

You need to use this particular syntax to find posts having a likes field containing an array that contains at least one embedded document that contains the field by with the value this.userId.

Meteor.publish("posts", function (cat) {
  return Songs.find({
    category: cat,
    postedAt: { $gte: Date.now() - 3600000 },
    "likes._id":this.userId
  },{
    fields:{
      likes:0
    }
  });
});

http://docs.mongodb.org/manual/tutorial/query-documents/#match-an-array-element

EDIT : answer was previously using $elemMatch which is unnecessary because we only need to filter on one field.

saimeunt
  • 22,666
  • 2
  • 56
  • 61
  • This approach works, but wouldn't using `$elemMatch` drop support for the oplog? [https://kadira.io/academy/optimize-your-app-for-oplog](https://kadira.io/academy/optimize-your-app-for-oplog). Or does this just happen with client-side queries? – Mazka Apr 23 '15 at 18:36
  • I'm sorry, I completely forgot was I was trying to achieve here. My first approach with using `forEach` was to filter the data on each post as well. This way the server would send a transformed one-field 'likes' array instead of 100 elements, which the user doesn't need. This is the approach I don't know how to achieve. – Mazka Apr 23 '15 at 19:23
  • In this case you should look at the fields option : see my edit, I removed completely the `likes` array from the returned docs. – saimeunt Apr 23 '15 at 19:56