Присоединяйтесь к коллекциям в mongodb - PullRequest
0 голосов
/ 18 июня 2020

Я пытаюсь получить данные из двух коллекций в одном ответе объекта json. Я пытаюсь объединить обе коллекции с помощью $ lookup, но это не работает:

db.getCollection('profiles').aggregate( [
 {
    { 
     $match: {_id: ObjectId(userId) } 
     },

     $lookup: {
                  from: "users",
                  localField: "user",
                  foreingField: "_id",
                  as: "user_data"  

                }
 }
])

в модели профиля пользователь объявлен следующим образом:

 user: {
        type: Schema.Types.ObjectId,
        ref: 'User',
        required: [ true, 'A reference to a user must exist']
    },

Это запрос отладки i в моей консоли можно увидеть:

Mongoose: users.aggregate([ { '$match': { _id: 5eec20720ff19056d079e953 } }, { '$lookup': { from: 'profile', localField: '_id', foreignField: 'user', as: 'profile_data' } }], {})

Ответы [ 2 ]

0 голосов
/ 19 июня 2020

Хорошо, наконец, я нашел решение благодаря ответу Армамедиа, но, честно говоря, я хотел бы понять, как я могу объединить эти две коллекции в одном объекте json. На данный момент я решил это вот так, с двумя запросами: один к коллекции профилей, а второй - к коллекции пользователей.

   const profile = await getUserProfile( userId, select );
   const user   = await User.find({"_id": userId}).select('email _id');

   return res.json({
        code: 200,
        data: {
            "name": profile[0].name,
            "email": user[0].email,
            "rate": profile[0].rate,    
        }

    })
0 голосов
/ 19 июня 2020

Пропустить, пока ... Ваш вопрос непонятен. Имя и фамилия пришли от пользователя? Если это так, вы можете сделать, как показано ниже:

const response = {
    code: 200,
    profile: {
        name: user.name,
        surname: user.surname,
        email: profile.email
    }
}

Затем вы можете преобразовать его в строку:

JSON.stringify(response);

Или отправить его как (если вы используете express):

response.send(response);

Пока здесь ...


РЕДАКТИРОВАТЬ: Теперь, когда я понял проблему, вот ответ:

Предположим, что ваши модели выглядят так, как показано ниже, и вы сохранили данные следующим образом:

const User = mongoose.model(
    'User',
    new mongoose.Schema({
        email: {
            type: String,
        },
    })
);
const Profile = mongoose.model(
    'Profile',
    new mongoose.Schema({
        name: {
            type: String,
        },
        rate: {
            type: Number,
        },
        user: {
            type: mongoose.Schema.Types.ObjectId,
            ref: User,
        },
    })
);

async function createAndSaveThem() {
    let user = new User({
        email: 'blah@blah.blah',
    });
    await user.save();
    let profile = new Profile({
        name: 'You',
        rate: 4,
        user: user._id,
    });
    await profile.save();
}

try {
    createAndSaveThem();
} catch (error) {
    console.log(error);
}

Вы можете использовать свои данные так, как хотите, вот так (без агрегирования):

async function getThem() {
    const profile = await Profile.findOne({ name: 'You'}).populate('user');

    const response = {
        code: 200,
        date: {
            name: profile.name,
            rate: profile.rate,
            email: profile.user.email
        }
    }    
    console.log('1', response); 
}

try {
    getThem();
} catch (error) {
    console.log(error);
}

Или это (с использованием агрегата):

async function getThemWithAggregate() {
    let profile = await Profile.aggregate([
        { $match: { name: 'You' } },
        {
            $lookup: {
                from: 'users',
                localField: 'user',
                foreignField: '_id',
                as: 'user',
            },
        },
        { $unwind: '$user' },
        { $project: { name: 1, rate: 1, email: '$user.email', _id: 0 } },
    ]);
    const response = {
        code: 200,
        date: profile[0]
    }    
    console.log(JSON.stringify(response,0,2)); 
}

try {
    getThemWithAggregate();
} catch (error) {
    console.log(error);
}

Оба будут выводить:

{
  "code": 200,
  "date": {
    "name": "You",
    "rate": 4,
    "email": "blah@blah.blah"
  }
}
...