Comments (6)
How you would make it on the client-side using autorun and Minimongo queries? Do the same on the server side.
from meteor-reactive-publish.
OK, got it...
maybe you want to add this code to your README as a multiple-cursor example?
Meteor.publish('all-posts-with-comments-and-authors', function () {
this.autorun(function (computation) {
const posts = Posts.find({})
// aggregate authors and comments
const authorIds = []
let commentIds = []
posts.forEach(function (post) {
authorIds.push(post.authorId)
commentIds = _.union(commentIds, post.commentIds)
})
const authors = Authors.find({ _id: { $in: authorIds } })
const comments = Comments.find({ _id: { $in: commentIds } })
// return multiple cursors
return [posts, authors, comments]
})
})
from meteor-reactive-publish.
Great! But just for the record, M2M joins are inefficient because at any change of any document, the whole autorun will rerun, republishing all documents. Only changes will be send to the client, so that is good, but this still means that diffs with previous documents will have to be computed. So, it is not so efficient.
I am not sure if this works (not tested the code), but probably this could be better:
Meteor.publish('all-posts-with-comments-and-authors', function () {
this.autorun(function (computation) {
const posts = Posts.find({}, {fields: {commentIds: 1}});
// aggregate comments
let commentIds = [];
posts.forEach(function (post) {
commentIds = _.union(commentIds, post.commentIds);
});
return Comments.find({ _id: { $in: commentIds } });
});
this.autorun(function (computation) {
const posts = Posts.find({}, {fields: {authorId: 1}});
// aggregate authors
const authorIds = [];
posts.forEach(function (post) {
authorIds.push(post.authorId);
});
return Authors.find({ _id: { $in: authorIds } });
});
return Posts.find({});
});
Here, we limit reactivity inside each autorun only really to fields we care about. So instead of autorun rerunning on any change of any fields of any document, we make it rerun only when really just data we care about changes.
Personally, I simply use multiple publish functions, or PeerDB, for such use cases.
from meteor-reactive-publish.
(Reopening until I document this.)
from meteor-reactive-publish.
If you want to optimize it even further (but please profile if it really optimizes anything), you could do even something crazy like:
const allCommentsIds = new ComputedField(function () {
const posts = Posts.find({}, {fields: {commentIds: 1}});
// aggregate comments
let commentIds = [];
posts.forEach(function (post) {
commentIds = _.union(commentIds, post.commentIds);
});
// so that set-equality is easy
commentIds.sort();
return commentIds;
}, EJSON.equals);
const allAuthorsIds = new ComputedField(function () {
const posts = Posts.find({}, {fields: {authorId: 1}});
// aggregate authors
const authorIds = [];
posts.forEach(function (post) {
authorIds.push(post.authorId);
});
// so that set-equality is easy
authorIds.sort();
return authorIds;
}, EJSON.equals);
Meteor.publish('all-posts-with-comments-and-authors', function () {
this.autorun(function (computation) {
return Comments.find({ _id: { $in: allCommentsIds() } });
});
this.autorun(function (computation) {
return Authors.find({ _id: { $in: allAuthorsIds() } });
});
return Posts.find({});
});
The difference here is that now computed field assures autorun will rerun only if content of IDs array really changes. Moreover, I moved computed fields out of the autorun. In this way it can be shared between multiple subscriptions.
BTW, you should also ask yourself if you really need M2M here. For example, is it really possible to have a comment without a post? If you want to publish all posts, then probably you can just go and publish all comments as well. There is no way to have a comment without a post anyway. And it might be then also useful to also simply publish all authors as well. For example, I often maintain count of how many posts each author has made anyway in the author's document. So you could blindly publish all authors which have the count larger than 0. So then you do not need any joins and any reactivity. Very performant.
A different story is if you need some parameters to pass. Like posts of only one author or something like that.
So, personally in MongoDB world an non-relational databases world it is pretty normal to denormalize data and then you can have quick queries. In general the idea is that you design your schemas according to queries you will be making. In most cases you do not need to support arbitrary queries, but only some known set of queries for your app, so you make a schema which has always all necessary fields for your queries in one document. And then it is really quick to make queries, because even database does not have to consult multiple tables, which means that you can do horizontal scaling very easily (joins across horizontally scaled instances is hard). I use PeerDB for automatic and reactive denormalization.
from meteor-reactive-publish.
Closing because I think this is not the best way to use this package.
from meteor-reactive-publish.
Related Issues (20)
- Probably we should not be doing handles.push(result) if handles is a computation
- After updating to Meteor 1.4.4.1 ReactiveVar is not defined HOT 14
- Multiple cursors for collection HOT 6
- Make sure DDP._CurrentPublicationInvocation is correctly set during autorun reruns HOT 1
- Update to latest server-autorun dependency HOT 3
- Error on Meteor Update 1.6.1 when using practicalmeteor:mocha HOT 48
- Re-using observers HOT 8
- it doesn't work with meteor 1.6.1 ? HOT 6
- Is reactive-publish expected to work with this.changed on a "virtual" collection? HOT 14
- Stopping subscription before it's ready can leave observers running forever HOT 2
- Question: How to publish to specific client side collection? HOT 2
- [Meteor 1.8.1] data not removed from client due to ddp-server internal changes HOT 12
- Question: Meteor 1.8.1 - ReferenceError: ReactiveVar is not defined HOT 4
- Update peerlibrary:reactive-mongo dependency to @0.3.0 HOT 3
- Nested autoruns on server is sending ready message before all autoruns are ready HOT 4
- Memory leak server crash with (0.3.0) HOT 2
- Issue with using observeChanges in autorun function HOT 4
- Update observing query changes patching
- The package overrides or ignores my Mongo poolSize setting HOT 1
- ReferenceError: ReactiveVar is not defined HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from meteor-reactive-publish.