In MongoDB, how can I retrieve an item and then add to an embedded document within it? - mongodb

I'm trying to do something similar to the following
http://mongoosejs.com/docs/embedded-documents.html
However instead of new BlogPost I'm trying to retrieve then add as follows
function addComment(id, comment, callback) {
Post.findOne(id, function(err, post) {
post.comments.push(comment);
});
}
I'm getting
TypeError: Cannot call method 'call' of undefined
What am I doing wrong? I left out the saving code for simplification it is crashing even without trying to save.

Assuming that the id parameter is an ObjectId or string (and not a query object), you should be calling findById instead of findOne.

Related

Getting Simple Objects from Mongoose Objects to Run Underscore's `_.difference()` Method

In my MongoDB backend I am using pre and post hooks to compare pre-save and post-save versions of a document, in order to handle post-processing when certain changes occur. I am also using underscore's _.difference() method to find the differences between the two versions of the document.
However, because these are not simple objects, but actually Mongoose objects, there is all sorts of additional data mixed in -- such as:
activePaths:
StateMachine {
paths: [Object],
states: [Object],
stateNames: [Array],
map: [Function] },
pathsToScopes:
So, long story short, I'm trying to figure out how to just get the object data - nothing else, so that _.difference will pull out the data that's changed. I tried using JSON.parse() but this didn't work in my case. I also tried calling the lean() Mongoose method on my two docs, but this caused a "not a function" error.
You can use the toObject() method on a document to convert it to a regular object.
The .lean() method can only be called on queries beforehand like this:
// passing options (in this case return the raw js objects, not mongoose documents by passing `lean`
Adventure.findById(id, 'name', { lean: true }, function (err, doc) {});
// same as above
Adventure.findById(id, 'name').lean().exec(function (err, doc) {});

Meteor/MongoDB limiting the result

I am trying to find all documents and publish at most 5 from the results.
Following this section of the MongoDB doc, I am trying to do this:
Meteor.publish('teams', function () {
return Teams.find().limit(5);
});
Yet, in the server console, I get an exception:
Exception from sub teams id Pm6jKL8Sv3FSDSTfM TypeError: Object [object Object] has no method 'limit'
The following works fine:
Meteor.publish('teams', function () {
return Teams.find({}, {limit:5});
});
Why does the second way work, rather than the first? And where can I find documentation for it?
Meteor's collection API is somewhat different from that of the mongo API. find takes up to two parameters: a selector object, and an options object. options allows you to specify such things as sort, skip, limit and fields, in addition to the meteor-specific reactive and transform.

Meteor - Cannot Access All Read Operations

I'm new to Meteor. I've been stuck on this problem for a while. I can successfully adds items to a collection and look at them fully in the console. However, I cannot access all of the read operations in my .js file.
That is, I can use .find() and .findOne() with empty parameters. But when I try to add .sort or an argument I get an error telling me the object is undefined.
Autopublish is turned on, so I'm not sure what the problem is. These calls are being made directly in the client.
This returns something--
Template.showcards.events({
"click .play-card": function () {
alert(Rounds.find());
}
})
And this returns nothing--
Template.showcards.events({
"click .play-card": function () {
alert(Rounds.find().sort({player1: -1}));
}
})
Sorry for the newbie question. Thanks in advance.
Meteor's collection API works a bit differently from the mongo shell's API, which is understandably confusing for new users. You'll need to do this:
Template.showcards.events({
'click .play-card': function() {
var sortedCards = Rounds.find({}, {sort: {player1: -1}}).fetch();
console.log(sortedCards);
}
});
See this for more details. Also note that logging a cursor (the result of a find) probably isn't what you want. If you want to see the contents of the documents, you need to fetch them.
Rounds.find().sort({player1: -1}) returns a cursor, so you will want to do this:
Rounds.find().sort({player1: -1}).fetch();
Note that this returns an Array of document objects. So you would do something more like this:
docs = Rounds.find().sort({player1: -1}).fetch();
alert(docs[0]);

In AngularJs, how to .get an object with nested objects from the database

I'm trying to get an object from MongoDB, the object has a nested object inside it (in this case the _id):
{_id:{$oid: 1234567}, title:'The title', content:'The content'},
{_id:{$oid: 8910111}, title:'different title', content:'different content'}, ...
Whenever i try to do a get via the angularjs-mongolab resource :
$scope.post = Posts.get({title: 'The title'}, function () {alert('loaded')});
It gives me a TypeError: Object #<Resource> has no method 'push' because its for some reason returning an array. When i do a .query instead of a .get with the same arguments, it returns the whole collection but with the _id returning a blank object {}
I think this is discussed on the angular github issues page here but i cant seem to relate this to my case. Anybody spotting anything wrong?

Verify that I am connected to my MongoDB via Mongoose?

I am trying to learn Node.js and using MongoDB.
I got an insert working correctly and can insert as many objects as I want, however I cannot seem to query them at all.
I have tried using every technique posted here and none of them return any of my objects.
I have verified via the Mongo console that the objects exist but I just can't query them and I am absolutely lost as to why.
Here is the current code I'm using to query:
User.findOne({ 'user.name': 'James' }, function(user){
console.log("Got " + user);
res.send(user);
});
Help?
EDIT
The above code returns "null".
Nearly every time I post a question on SO lately I seem to find the answer myself within 15 minutes.
The answer to this one, is that my callback function is only accepting 1 argument of "user". The first argument in the callback is any Errors that are raised, so obviously there are no errors raised.
Changing the callback to this fixes it:
function(err, user) {
}