Reputation: 389
So I'm using node v10, mongodb v4.2 and mongoose v5.9.
I have a UsersSchema:
const UsersSchema = new Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
lowercase: true
},
...
A CompaniesSchema:
const CompaniesSchema = new Schema({
name: {
type: String,
required: true,
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Users',
required: true
},
branches: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Branches'
}]
...
})
And a BranchesSchema:
const BranchesSchema = new Schema({
name: {
type: String,
required: true,
},
company: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Companies',
required: true
}
users: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Users',
}]
})
I need to query all the companies the user own, OR the companies he's been added to a branch. I tried to do like:
const id = 'MY_USER_ID'
const queryCompanies = await Companies.find({
$or: [{ user: id }, { "branches.users": [id] }],
});
The { user: id }
part works. I'm having trouble trying to query the companies he's in based on the branches he's in. Is that even possible?
Upvotes: 1
Views: 55
Reputation: 22296
With the current schema setup you have 2 options:
const id = 'MY_USER_ID';
let companyIds = await Branches.distinct("company", {users: id});
const queryCompanies = await Companies.find({
$or: [{ user: id }, { _id: {$in: companyIds} }],
});
const id = 'MY_USER_ID';
const queryCompanies = await Companies.aggregate([
{
$lookup: {
from: "branches",
let: {companyId: "$_id", userId: id},
pipeline: [
{
$match: {
$expr: {
$and: [
{
$eq: ["$$companyId", "$company"]
},
{
$setIsSubset: [["$$userId"], "$users"]
}
]
}
}
}
],
as: "branches"
}
},
{
$match: {
$or: [
{
user: id
},
{
"branches.0": {$exists: true}
}
]
}
}
]);
I personally recommend option 1 as Mongo does not like lookuping, especially here where you have to do so on the entire collection.
Upvotes: 1