-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
push/pop-like operator for array based fields #39
Comments
I was thinking about solving this problem and introducing c.set('members', []);
c.members.push({
name: 'Name'
}); It will still detect the changes and update them. There is also one more feature that needs implementing. When a new member gets pushed into the array and the document is saved then all members will be saved to the database (not just the one that was pushed). I have to implement detection of changes (diff between arrays). |
Thanks for the workaround; That will suffice for me at the moment as I don't foresee my arrays growing more than a set limit. But for future optimization, diffing between arrays would be ideal to reduce I/O in mongo. |
Yes right. I definitely have to figure something out. |
That workout didn't work for me? When I try it I get this: Shouldn't it be: members: { 'Name' } ? I'm trying to add an item to an array, it's proving difficult, do I need to use collection.update on this? One great thing about astronomy that I've really liked is not having to write these methods. |
Could you paste here the code that is not working for you? |
Hi Jagi, found.set('source', []); On August 3, 2015 at 4:12:24 AM, jagi (notifications@github.com) wrote: Could you paste here the code that is not working for you? — |
When you have class / model: Founds = new Mongo.Collection('founds');
Found = Astro.Class({
collection: Founds,
fields: {
source: {
type: 'array',
default: []
}
}
}); then you can do as follows: var found = new Found();
found.set('source', []); // This line is necessary because we defined default value for the "source" field.
found.source.push({
name: 'abc'
});
found.save(); The Is this exactly what you expect? |
That's what I'm going for, how do I get it to work for 'updates'? It seems like this would overwright the array (with found.set('source', [])) |
With updates it works as well but you don't need to You just write: var found = Founds.findOne();
found.source.push({
name: 'abc'
});
found.save(); That's it |
That's great, so then I assume if it's a non-keyed array, it would looke like this: found.source.push('newarrayvalue')? |
Yes exactly |
This seems to get a little funny with the Meteor.users collection. For one, the collection only allows modifying emails, services, and profiles, so I had to re-work my schema a bit to not get permission errors. |
Instead writing: user.profile.set('someArray', []); you have to write: user.set('profile.someArray', []); In your schema, you also have to define it like this: User = Astro.Class({
/* ... */
fields: {
'profile': {
type: 'object',
default: {}
},
'profile.someArray': {
type: 'array',
default: []
}
}
}); Maybe it's seems to be a little bit not intuitive. However in the next release, it will change a little bit to something like this: This code is for the version 0.13.0 (NOT YET RELEASED) Profile = Astro.Class({
name: 'Profile',
fields: {
name: {
type: 'String'
},
someArray: {
type: 'Array',
default: []
}
}
});
User = Astro.Class({
name: 'User',
collection: Meteor.users,
fields: {
emails: 'Array',
services: 'Object',
createdAt: 'Date',
profile: {
type: 'Profile',
default: {}
}
}
}); Thanks to that you will have more control over your data and it will be possible to do something like this: user.profile.set('someArray', []); as well as this: user.set('profile.someArray', []); |
Huh, I could have sworn I tried that, but I just switched it to what you suggested and it worked perfectly. I'm sure the new way will be very powerful, but it looks more confusing to me... (note: I'm pretty new to this stuff, so take it with a grain of salt.) What does it mean to have nested Astro classes? Can you embed another class inside that one? Is it basically creating a reusable schema, and can you use a class to extend another one, or only to define fields? Thanks! |
I'm working on this new release because I want Astronomy to work not only with MongoDB but also with other databases also relational. In most relational databases you can have nested objects or arrays like for instance the var user = {
username: 'jagi',
emails: [ // In SQL databases it would be moved to external table
{ address: "cool@example.com", verified: true },
{ address: "another@different.com", verified: false }
],
profile: {}, // In SQL databases it would be moved to external table
services: {} // In SQL databases it would be moved to external table
}; However in MongoDB or RethinkDB it's possible. So my solution for Astronomy to make it work with other databases is Nested classes. For example you define that emails are of the Moreover it will be easier to perform many operations because classes are gonna be flat (set of first class fields - no nested fields definition). Nested fields definition will be achieved by using nested classes. I hope it explains everything. If not, let me know I will try to describe it better :) |
That makes sense, it's very forward-thinking. What about other class attributes, like what would happen if you put methods on a class that you nested as a field type? That's what really confuses me, that you use the same class to define embedded fields as you do to define the collection objects. On the one hand, it's a very elegant approach, but on the other it seems a bit unstructured, at least visually. |
The difference is in the presence of |
I'll just wait and see :) |
I've got a question. If i have a field of type array, which in this case, represent the history of the class (for example, an history of the change in prices for an article...). I don't want to pull the full history in memory every time the user is gonna make a change, it could become heavy with time... And because of this, if y try to do in an update :
It won't work has it's gonna override the values already there... |
var product = Products.findOne();
product.history.push({
price: priceValue
});
product.save(); The save method will save entire Products.update(product._id, {
$push: {
history: {price: priceValue}
}
}); However, in this situation you have to create your own validation logic. With the new Astronomy release there will be a way to perform validation also in such situations. |
Yup, i was already using the classic mongo query on this one. It's not really a problem since i use it in a behaviors where the values have already been validated. |
Ok good to hear :). I'm trying to do my best :) |
I've implemented the |
Awesome. Just so i understand properly, this new version will give me the possibility to push inside an array without having it in memory and without erasing the data already there ? |
No, it just introduces |
Ok, i guess i'll see directly on the documentation to fully get everything this new version will bring ;) |
Currently, the only way to work with array-type fields is to explicitly specify them by index:
It would be nice to have a way to push a new element onto the array like so:
The text was updated successfully, but these errors were encountered: