3

Bulding an API with node.js/express and mongoDB. I have two collections with like a many to many relation, Users and Items. I want to get all the Items that the User are following. The users Items is an array with ids referring to Items.

How do i query so i get all the Items thats in the useritems array?

Collections:

Users:

{
    email: "[email protected]",
    username: "johnny",
    useritems: ["51e101df2914931e7f000003", "51cd42ba9007d30000000001"]
}

Items:

{
       "name": "myitem",
       "description": "Description of item" 
       "_id": "51e101df2914931e7f000003"
}

{
       "name": "myitem2",
       "description": "Description of item2" 
       "_id": "51cd42ba9007d30000000001"
}

{
       "name": "myitem3",
       "description": "Description of item3" 
       "_id": "51e101df2914931e7f000005"
}

EDIT:

I updated the code. I now get the array of useritems ids based on the user id. Problem is when i try to send the items to array. Items is always empty. Is something wrong with my query?

exports.findItemsByUserId = function(req, res) {
    //var id = req.params.id;

   var userId = "51e6a1116074a10c9c000007"; //Just for testing

    db.collection('users', function(err, collection) {
        collection.findOne({'_id':new BSON.ObjectID(userId)}, function(err, user) {

            db.collection('items', function(err, collection) {

                console.log("user undefined? ",user);
                console.log("useritems ",user.useritems);
                collection.find({'_id': {'$in' : user.useritems}}).toArray(function(err, items) {
                    console.log("useritems ",user.useritems); // <--Gets me array with the ids
                    console.log("items ", items); //<--Empty
                    res.send(items);//Empty
                });
            });
        });
    });
};

2 Answers 2

1

Maybe this is more like it?

exports.findItemsByUserId = function(req, res) {
  var userId = "51e101df2914931e7f000003"; //Just for testing
  var user = db.users.find({"_id": userId});

  var items = db.items.find({'_id': {'$in' : user.useritems}});
  res.send(items.toArray());
};
Sign up to request clarification or add additional context in comments.

5 Comments

That does'nt work. I'm new to mongoDB and nosql databases. In MySql for exampel I would just create a useritems table with userid and itemid as foreign keys. But i cant get these relations to work with mongoDB
Still gets the; TypeError: Cannot call method 'find' of undefined
What line? You only call find on your 'users' and 'items' collections, so one of those objects is undefined...JavaScript is case sensitive, and you capitalise them sometimes... console.log is very helpful for showing the contents of objects at different points in the program.
I updated my code. Console.log is helping me. The problem now is that items always are empty. Is my query to to get all items from an array with ids wrong?
I think you want the callback function as the second argument to the find method - not as an argument to the 'toArray' function.
0

Problem solved. Not the most fancy solution but it works. Just looping through some arrays. Guess there's some proper query for this.

exports.findItemsByUserId = function(req, res) {
   var id = req.params.id; //<--- was disabled, it will give an error when testing this code.

   var userId = "51e6a1116074a10c9c000007"; //Just for testing

    db.collection('users', function(err, collection) {
        collection.findOne({'_id':new BSON.ObjectID(id)}, function(err, user) {

            db.collection('items', function(err, collection) {
                var itemsArray = []

                var itemIds = user.useritems

                for (var i = 0; i < itemIds.length; i++) {
                    itemIds[i]

                    collection.findOne({'_id':new BSON.ObjectID(itemIds[i])}, function(err, item) {

                    itemsArray.push(item);

                    if(itemIds.length === itemsArray.length){

                        res.send(itemsArray);

                    }

                    });
                };

            });
        });
    });
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.