How to get element property from array in Mongoose? - mongodb

I have document structure like this in my schools collection
I am searching school by its code from array of codes School.findOne({ 'codes.code': '12345678' }) and I am getting my school but I also want to get code.type property from code object where my code is 12345678. Should i use javascript Array.find?

What you can do is selecting the matching array element by
School.find({ 'codes.code': '12345678' }, {"codes.$":1})
Otherwise, yes, you need to find the element in the array:
var myschool = School.find({ 'codes.code': '12345678' })[0]
myschool.codes.find(c => c.code == '12345678')

Related

Newbie get _id of returned where query

Selecting specific item from returned query (newbie)
Using laravel with the https://github.com/jenssegers/laravel-mongodb#query-builder package so the php is a bit off the norm for MongoDB terminology
I query the database like so:
$role_id = Role::where('name', 'Admin')->get();
How do I access the '_id' of the returned query?
I would like to grab the '_id' in a variable
get() returns Illuminate\Support\Collection object. That means you are getting an array of return items. So, in your case, you should iterate $role_id to loop through the items and get _id. Like this -
foreach ($rid as $role_id) {
echo $rid->_id;
}

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});

Referencing property in mongoDB by taking _id

I have a collection which have a document like this:
collection 1
{
_id: ObjectID(),
name: foo
}
I would get ObjectID of the above collection and copy into a document of another collection in order to reference correctly. Should I do simply:
db.collection1.find({name:"foo"},{_id:1})
EDIT
A call to find will return a cursor. Cursors works like an iterator in other languages. You can either attempt to find the first element in the cursor using the next() function and then get it's _id property or simplify your statement using findOne:
var x = db.collection1.findOne({name:"foo"}, {_id:1});
var id = x._id;
This is making an assumption that you are getting a document back from that query. You'll probably want to add a null check on x before grabbing the _id property.

Fetch Record from mongo db based on type and ancestry field

in mongodb records are store like this
{_id:100,type:"section",ancestry:nil,.....}
{_id:300,type:"section",ancestry:100,.....}
{_id:400,type:"problem",ancestry:100,.....}
{_id:500,type:"section",ancestry:100,.....}
{_id:600,type:"problem",ancestry:500,.....}
{_id:700,type:"section",ancestry:500,.....}
{_id:800,type:"problem",ancestry:100,.....}
i want to fetch records in order like this
first record whose ancestry is nil
then all record whose parent is first record we search and whose type is 'problem'
then all record whose parent is first record we search and whose type is 'section'
Expected output is
{_id:100,type:"section",ancestry:nil,.....}
{_id:400,type:"problem",ancestry:100,.....}
{_id:800,type:"problem",ancestry:100,.....}
{_id:300,type:"section",ancestry:100,.....}
{_id:500,type:"section",ancestry:100,.....}
{_id:600,type:"problem",ancestry:500,.....}
{_id:700,type:"section",ancestry:500,.....}
Try this MongoDB shell command:
db.collection.find().sort({ancestry:1, type: 1})
Different languages, where ordered dictionaries aren't available, may use a list of 2-tuples to the sort argument. Something like this (Python):
collection.find({}).sort([('ancestry', pymongo.ASCENDING), ('type', pymongo.ASCENDING)])
#vinipsmaker 's answer is good. However, it doesn't work properly if _ids are random numbers or there exist documents that aren't part of the tree structure. In that case, the following code would work rightly:
function getSortedItems() {
var sorted = [];
var ids = [ null ];
while (ids.length > 0) {
var cursor = db.Items.find({ ancestry: ids.shift() }).sort({ type: 1 });
while (cursor.hasNext()) {
var item = cursor.next();
ids.push(item._id);
sorted.push(item);
}
}
return sorted;
}
Note that this code is not fast because db.Items.find() will be executed n times, where n is the number of documents in the tree structure.
If the tree structure is huge or you will do the sort many times, you can optimize this by using $in operator in the query and sort the result on the client side.
In addition, creating index on the ancestry field will make the code quicker in either case.

Using nodejs : mongodb find then add to Array

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.