I would like to get a user from the database. My function takes in a requesterId
which is the ID of the user requesting this data, and a targetId
which is the user to retrieve.
If the requester is in the target's friends
array (strings), the phone
field should be included in the projection. If not, it is excluded.
I have come up with the following query after reading the example here. However, the phone
field is always returned no matter what. What am I doing wrong?
getUser: function getUser(requesterId, targetId) {
return db.collection('users').aggregate([
{$match: {userId: targetId}},
{
$project:
{
firstName: 1,
phone: {
$cond: {
if: {friends: requesterId},
then: "$phone",
else: "$$REMOVE"
}
}
}
},
{$limit: 1}
]).toArray();
}
Schema (created in Compass so no code):
userId
- String
firstName
- String
friends
- Array(String)
phone
- String
Indices: None on this collection
Example:
/* Bob's MongoDB data */ {userId: "BobID", firstName: "Bob", friends: ["AmyID"], phone: "1234567890"}
getUser(requesterId = 'AmyID', targetId = 'BobID');
/* Result */ {firstName: "Bob", phone: "1234567890"}
/* Amy's MongoDB data */ {userId: "AmyID", firstName: "Amy", friends: ["CassieID"], phone: "9876543210"}
getUser(requesterId = 'BobID', targetId = 'AmyID');
/* Result */ {firstName: "Amy", phone: "987654321"}
Bob's request for Amy's user should not return her phone number because he is not in her friends
array.
The if:
value must be a boolean expression, not a query object. To check whether a specified value is in an array, you can use the $in
expression:
db.collection('users').aggregate([
{$match: {userId: targetId}},
{
$project:
{
firstName: 1,
phone: {
$cond: {
if: {$in: [requesterId, '$friends']},
then: "$phone",
else: "$$REMOVE"
}
}
}
},
{$limit: 1}
])