Reputation: 103
Im having a real headache with a mongoose query, I am still quite new to it and wondered if anyone could suggest a solution.
I have the following fields in a gallery collection.
status (value of 'public' or 'restricted'),
restriction (value of 'canview' or 'cantview'),
canview (an array of user ids (ObjectIds) of users permitted to view gallery)
I then check fields against the current userID, to see what items are viewable.
how would it be possible to select ALL of the following items
a) all items with 'status' = 'public'
b) all items with 'status' = 'restricted' WHERE 'restricted' = 'canview' AND 'canview' contains the UserID
I wasnt able to do this using $and and $or, so tried with $where instead. Using the following global function
var existsInArray = function(str,arr) {
// nb: remember we have typeof ObjectID, so lets convert to strings first!
var newarr = arr.toString().split(',');
// now compare..
if(newarr.inArray(str)) {
return true;
}
return false;
};
I was hoping to do something like this...
exports.listviewable = function(req, res) {
var reqID = req.user.id;
Gallery
.find()
.$where(function () {
return this.status === "public" || ( this.status === "restricted" && this.restriction === "canview" && existsInArray(reqID, this.canview));
})
.sort('-created')
.exec(function(err, galleries) {
if(err) {
return res.status(400).send({message:getErrorMessage(err)})
} else {
res.json(galleries);
}
});
};
but this wasnt working - it appears I wasnt able to use the global existsInArray function in the $where clause ?
Is it possible to do it like this ( similar unresolved question here how to call external function in mongoose $where and passing this variable), or is there a better way to do it with AND and OR ?
Upvotes: 0
Views: 3318
Reputation: 937
Hey I'd recommend hitting the mongo docs - they have alot of info on this.
a)
Gallery.find({status: 'public'}, function(err, data){
console.log(data)
});
b)
Gallery.find({status: 'restricted', restricted: 'canview', canview: reqID }, function(err, data){
});
or both together with sorting...
Gallery.find({$or:[
{status: 'public'},
{status: 'restricted', restricted: 'canview', canview: reqID }
]}, {
sort:{created:-1}
}, function(err, data){
console.log(data)
});
Upvotes: 1
Reputation: 312035
A $where
function can't refer to your local existsInArray
function because the $where
function is executed on the server where that local function doesn't exist.
But you shouldn't be using $where
anyway, as you can do with with a simple $or
query that takes advantage of the fact that you can directly query array fields like canview
with "contains" behavior:
Gallery
.find({
$or: [
{status: 'public'},
{status: 'restricted', restriction: 'cantview', canview: reqId}
]
})
.sort('-created')
.exec(function(err, galleries) {...});
Upvotes: 0