Question

I have a (simplified) model based on the following schema:

schema = mongoose.Schema({
    foo: { type: String },
    bars: [{ type: String }]
});
model = mongoose.model ('model', schema);

and I want to create an API to return all documents that contain all of the 'bars' which are provided in a comma separated list. So I have:

exports.findByBars = function (req, res) {
  var barsToFind = req.body.bars.split(',');
  // find the matching document
};

Does Mongoose provide an API for this or is there a query param I can pass to Model#find to get this functionality? I only want a document to be returned if its bar property contains all of the values in the barsToFind array.

Was it helpful?

Solution

There are ways to structure your query to do this, the approaches are different depending on your mongodb server version. So following on from your code:

For MongoDB version 2.6 and above, use the $all operator:

model.find({
    "bars": { "$all": barsToFind }
},

And though the operator does exist for previous versions, it behaves differently so you actually need to generate an $and statement to explicitly match each entry:

var andBars = [];

barsToFind.forEach(function(bar) {
    andBars.push({ "bars": bar })
});

model.find({
    "$and": andBars
},

Both ensure that you only match documents that contain all of the entries in the array as you have specified, it's just that the syntax available to MongoDB 2.6 is a little nicer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top