Пн goose массив запросов внутри массива объектов - PullRequest
1 голос
/ 28 мая 2020

Итак, я использую node v10, mongodb v4.2 и mon goose v5.9.

У меня есть UsersSchema:

const UsersSchema = new Schema({
    name: {
        type: String,
        required: true,
    },
    email: {
        type: String,
        required: true,
        lowercase: true
    },
 ...

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'
    }]
    ...

})

И 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',
    }]
})

Мне нужно запросить все компании, которыми владеет пользователь, ИЛИ компании, в которые он был добавлен в филиал. Я пробовал делать как:

const id = 'MY_USER_ID'
const queryCompanies = await Companies.find({
  $or: [{ user: id }, { "branches.users": [id] }],
});

Часть { user: id } работает. У меня проблемы с запросом компаний, в которых он работает, по филиалам, в которых он работает. Возможно ли это?

1 Ответ

1 голос
/ 29 мая 2020

При текущей настройке схемы у вас есть 2 варианта:

  1. Разделить на 2 вызова:
const id = 'MY_USER_ID';
let companyIds = await Branches.distinct("company", {users: id});
const queryCompanies = await Companies.find({
    $or: [{ user: id }, { _id: {$in: companyIds} }],
});

Используйте $ lookup
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}
                }
            ]
        }
    }
]);

Я лично рекомендую вариант 1, так как Mon go не любит поиск, особенно здесь, где вы должны делать это на всем сборник.

...