Using nodejs : mongodb find then add to Array - mongodb

I made a simple db with a few users in it with mongodb and nodejs. Next im looping through the list and display the users in the list's names etc with sys.puts().
No I am adding the users to an Array() like this:
db.open(function(err, db) {
db.collection('users', function(err, collection) {
collection.find({}, {'sort':[['name', 1]]}, function(err, cursor) {
cursor.each(function(err, user) {
if(user != null) {
users[user._id] = { 'name':user.name, 'email': user.email };
sys.puts(">> Adding user to list... "+ user.name);
}
});
db.close();
});
});
});
Is this how I add the users to the array? Because the users.lenght = 0. Im a bit lost now

What you are doing is setting properties on the array object, that might be a bit confusing.
[] is both used for indexes and keys, that means in case of your array, users[0] will return the first element in the array, but users['blaid12'] will get/set the property blaid12' on the array object, that's like doingusers.blaid12`.
So in the end your array becomes more like a hashmap. The length property does not count the properties of the object, it counts the elements in the array.
You have a couple of ways of solving the issue:
Use an object {} and use the user ids as keys on that object, you'll have to keep track of the user count via another variable.
Use the array as an array by using users.push({'name':...}) to append elements to the array, if you need the userid too, then just add it to the object you push into the array.
Go with a mixed approach, use an array to push the values, and then an object to map the ids to the array indexes.

Related

Mongoose Populate Returning ObjectIds and Empty Arrays

I have an Collection Model that has a property of items that holds an array of Item Models.
const CollectionSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
items : [{type : mongoose.Schema.Types.ObjectId, ref: 'Item'}]
});
I tried to populate the items array in order to get the objectId's properties, but the items array would return back empty. (The code below is how I populated the items array. I first found the collection I was looking for by the _id using the req.body.search. I then ran .populate("items") in order to populate the items array. What I got back was an empty items array.)
userRouter.post('/iList', passport.authenticate('jwt', {session: false}), (req, res) => {
Collection.findById({_id : req.body.search}).populate("items").exec((err, document) => {
if(err)
res.json(err)
else
res.json({item: document})
})
});
I know my items array isn't empty since I can check on mongoDB that it is full.
The image of my mongoDB collection with an items array that isn't empty.
The weird thing is that if I put "collections" into the .populate params, my Items array does return with stuff, but it only returns the ObjectIDs and not actual object properties. I am confused to why .populate("items") isn't working.
If you are using findById then why are you specifying {_id: req.body.search}. If your req.body.search is a type of mongoose ObjectId string then you can directly use findById(req.body.search) instead of that. Also you can use simply the projection. Second argument in find calls are projections
If you are trying get items array only then why don't you try this query:-
Collection.findById(req.body.search, {items: 1}).then((result) => {
console.log('Items are :-\n', result);
}, (err) => {
console.log(err);
})
1 means include and 0 means exclude. So items will be present in output, also _id is default in output. In case you want to exclude _id then you can change second parameter to this -> {items: 1, _id: 0}
Never mind. The issue was when I pushed the Item Models via mongoose, I forgot to do items.save() which meant the items array held nothing.

Is There a way to fetch data from mongodb Collection using in Array function. if array id is string

I have Generating the Dynamic Report from mongodb Collections. I fetch Data from one Collection and e.g client and take all client id in Array e.g ["5b7869dff0be71721f53d2e3","5b7869dff0be71721f53d2e4","5b7869dff0be71721f53d2e3"] When i I fetch data from other collection using In Array e.g {"clientId": { $in: inArray } } it give me empty result. because in array work if i put { "clientId": { $in: [ObjectId('5b785f243cc6c746af635dc8')] } } "ObjectId" word before the id. My Question is how i Put this ObjectId work in the array.
you can use map to map the array to an array of ObjectId
inArray = inArray.map( value => ObjectId(value) );

Meteor, mongodb - accessing an object inside an array

Alright, so I have a collection called Polls. Inside the Polls "table" there is an attribute called choiceObjects which is an array of objects. Each object inside this array has its own attributes. What I need to do is update one of the attributes there. Ill give you a screen shot so you can better visualise what Im talking about
As you can see the choice objects have attributes like body, country etc. There is another attribute called pollid which is set to optional and therefore you cant see it right now. I need to update this pollid attribute now that I have acess to the pollid
Polls.update(
{ _id: pollId },
{ "$set": { "choiceObjects": { pollid: pollId } } }
); //this is kind of what Im trying to do but this isnt right
Since then... I have further tried the following :
var selectedpoll = Polls.findOne(pollId);
console.log(selectedpoll);
//Polls.update( selectedpoll, {"$set"{'choiceObjects.$.pollId':pollId}},false, true );
but when i try that i get the error : the positional operator did not find the match needed from the query. unexpanded update: choiceObjects.$.pollId
If I understand your objective correctly, you want to update (or add) pollid to all objects in the choiceObjects array. Unfortunately $, $push, $addToSet only work with single elements AFAIK.
This might not be what you are looking for but one possible and very obvious way to approach this problem would be to update the entire array in the collection i.e.
var choiceObjects = Polls.findOne({_id: pollId}).choiceObjects;
for (var i = 0; i < choiceObjects.length; i++) {
choiceObjects[i].pollid = pollid;
}
Polls.update({_id: pollid}, {choiceObjects: choiceObjects});

How to Iterate through Object inside Collection Meteor Mongo

If I do the following search:
VideoCourses.find({'_id': 'jkwehrjewrew'}).fetch()[0].videos
I get the following:
Object {first: "firstvideo.html", second: "secondvideo.html", third: "thirdvideo.html"}
My question, is how can iterate through the collection. I want to render one video at a time, so I can render the first video, and then on click, render the second, etc.
The thing is, I have many sets of videos, so this should be done dynamically. It should iterate through the next video.first, video.second.. etc.
Is that possible? I've looked into .next() but I think that works for an entire collection, not an object inside the collection.
Thank you in advance!
This is a JavaScript question, not necessarily Meteor. Use a for-in loop to iterate through objects.
// This query returns an object
var MyObject = VideoCourses.find({'_id': 'jkwehrjewrew'}).fetch()[0].videos
// The object is brings back looks like this:
// {
// first: "firstvideo.html",
// second: "secondvideo.html",
// third: "thirdvideo.html"
// };
// Use a for-in loop to iterate through the object
for(key in myObject){
console.log("this is the key: ", key, ", and this is the value: ", myObject[key]);
};

mongo: multiple queries or not?

I'm wondering the best way to query mongo db for many objects, where each one has an array of _id's that are attached to it. I want to grab the referenced objects as well. The objects' schemas looks like this:
var headlineSchema = new Schema({
title : String,
source : String,
edits : Array // list of edits, stored as an array of _id's
...
});
...and the one that's referenced, if needed:
var messageSchema = new Schema({
message : String,
user : String,
headlineID : ObjectId // also contains a ref. back to headline it's incl. in
...
});
One part of the problem (well, depending if I want to keep going this route) is that pushing the message id's is not working (edits remains an empty array [] afterwards) :
db.headline.update({_id : headlineid}, {$push: {edits : messageid} }, true);
When I do my query, I need to grab about 30 'headlines' at a time, and each one could contain references to up to 20 or 30 'messages'. My question is, what is the best way to fetch all of these things? I know mongo isn't a relational db, so what I'm intending is to first grab the headlines that I need, and then loop through all 30 of them to grab any attached messages.
db.headline.find({'date': {$gte: start, $lt: end} }, function (err, docs) {
if(err) { console.log(err.message); }
if(docs) {
docs.forEach(function(doc){
doc.edits.forEach(function(ed){
db.messages.find({_id:ed}, function (err, msg) {
// save stuff
});
});
});
}
});
This just seems wrong, but I'm unsure how else to proceed. Should I even bother with keeping an array of attached messages? I'm not married to the way I've set up my schema, either. If there is a better way to track relationships between them, or a better query to achieve this, please let me know.
Thanks
Does each message belong to only one headline? If so, you can store the headline id as part of each message. Then for each headline, do:
db.messages.find({headline_id: current-headline-id-here})
You could try using the $in operator for selecting a list of ObjectIds
http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24in