0

I've been successfully using $in in my node webservice when my mongo arrays only held ids. Here is sample data.

{
    "_id": {
        "$oid": "52b1a60ce4b0f819260bc6e5"
    },
    "title": "Sample",
    "team": [
        {
            "$oid": "52995b263e20c94167000001"
        },
        {
            "$oid": "529bfa36c81735b802000001"
        }
    ],
    "tasks": [
        {
            "task": {
                "$oid": "52af197ae4b07526a3ee6017"
            },
            "status": 0
        },
        {
            "task": {
                "$oid": "52af197ae4b07526a3ee6017"
            },
            "status": 1
        }
    ]
}

Notice that tasks is an array, but the id is nested in "task", while in teams it is on the top level. Here is where my question is.

In my Node route, this is how I typically deal with calling a array of IDs in my project, this works fine in the team example, but obviously not for my task example.

app.get('/api/tasks/project/:id', function (req, res) {
    var the_id = req.params.id;
    var query = req.params.query;
    models.Projects.findById(the_id, null, function (data) {

        models.Tasks.findAllByIds({
            ids: data._doc.tasks,
            query: query
        }, function(items) {

            console.log(items);
            res.send(items);
        });
    });
});

That communicates with my model which has a method called findAllByIds

module.exports = function (config, mongoose) {
    var _TasksSchema = new mongoose.Schema({});

    var _Tasks = mongoose.model('tasks', _TasksSchema);

    /*****************
     *    Public API
     *****************/
    return {

        Tasks: _Tasks,


        findAllByIds: function(data, callback){
            var query = data.query;

            _Tasks.find({_id: { $in: data.ids} }, query, function(err, doc){
                callback(doc);
            });
        }
    }

}

In this call I have $in: data.ids which works in the simple array like the "teams" example above. Once I nest my object, as with "task" sample, this does not work anymore, and I am not sure how to specify $in to look at data.ids array, but use the "task" value.

I'd like to avoid having to iterate through the data to create an array with only id, and then repopulate the other values once the data is returned, unless that is the only option.

Update

I had a thought of setting up my mongo document like this, although I'd still like to know how to do it the other way, in the event this isn't possible in the future.

"tasks": {
            "status0": [
            {
                "$oid": "52995b263e20c94167000001"
            },
            {
                "$oid": "529bfa36c81735b802000001"
            }
        ],
            "status1": [
            {
                "$oid": "52995b263e20c94167000001"
            },
            {
                "$oid": "529bfa36c81735b802000001"
            }
        ]
        }
2
  • How is your mongoose model structured? Commented Mar 11, 2014 at 7:15
  • I added in more of my node model code, minus all the irrelevant stuff Commented Mar 11, 2014 at 7:25

2 Answers 2

0

You can call map on the tasks array to project it into a new array with just the ObjectId values:

models.Tasks.findAllByIds({
    ids: data.tasks.map(function(value) { return value.task; }),
    query: query
}, function(items) { ...
Sign up to request clarification or add additional context in comments.

Comments

0

Have you try the $elemMatch option in find conditions ? http://docs.mongodb.org/manual/reference/operator/query/elemMatch/

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.