#mongodb #mongoose
Вопрос:
У меня есть две схемы:
const userSchema = new Schema(
{
username: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
},
{
timestamps: true,
}
);
const userLikeSchema = new Schema(
{
userId: {
type: String,
required: true,
ref: 'User',
},
likedUserId: {
type: String,
required: true,
ref: 'User',
},
isActive: {
type: Boolean,
required: true,
default: true,
},
},
{
timestamps: true,
}
);
Я пытаюсь получить список пользователей, упорядоченных по убыванию их количества лайков.
Я не уверен, что схема, которую я использовал в sql, верна.
Я написал следующий запрос:
const likedUsers = await UserLike.aggregate(
[
{
$group: {
_id: '$likedUserId',
likes: { $sum: 1 },
},
},
{ $sort: { likes: -1 } },
{
$lookup: {
from: 'users',
localField: 'likedUserId',
foreignField: '_id.str',
as: 'user',
},
},
]
);
Я пытаюсь получить такой результат, как:
[
{
"_id": "604bb648be8680063009fddc",
"likes": 2,
"user": {
"_id": "604bb648be8680063009fddc",
"username": "muhamed",
"password": "$2b$10$EVYWZb4vl2TFGmIrCWe1sO/QogdU6/Ui8TgujY4PMKLJKIVOzmOi6",
"createdAt": "2021-03-12T18:43:20.806Z",
"updatedAt": "2021-03-12T18:46:17.635Z",
"__v": 0
},
}
]
Но вместо этого я получаю следующее, в котором отображается каждый пользователь для каждого элемента:
[
{
"_id": "604bb648be8680063009fddc",
"likes": 2,
"user": [
{
"_id": "604bb648be8680063009fddc",
"username": "muhamed",
"password": "$2b$10$EVYWZb4vl2TFGmIrCWe1sO/QogdU6/Ui8TgujY4PMKLJKIVOzmOi6",
"createdAt": "2021-03-12T18:43:20.806Z",
"updatedAt": "2021-03-12T18:46:17.635Z",
"__v": 0
},
{
"_id": "604bc703ea4bf93fb427056a",
"username": "krasniqi",
"password": "$2b$10$dnKumHhKNIfA6BM3uekymOpIdMFuQy9aYYKmGBxnW401CjTAuMLIy",
"createdAt": "2021-03-12T19:54:43.368Z",
"updatedAt": "2021-03-12T19:54:43.368Z",
"__v": 0
},
{
"_id": "604c90ab9f7b970cd46ff668",
"username": "matin",
"password": "$2b$10$CEUCaGk.JF5PBwsTBE3fRufVXzUBt.eLyo28eTt8zhBezVSFflMhS",
"createdAt": "2021-03-13T10:15:07.877Z",
"updatedAt": "2021-03-13T10:15:07.877Z",
"__v": 0
}
]
},
]
Что я упускаю ?
Ответ №1:
Я думаю, что здесь есть проблема _id.str
.
Вы неправильно настроили свою пользовательскую систему. Вы должны были указать поля type
своего идентификатора mongoose.Schema.ObjectId
:
const userLikeSchema = new Schema(
{
userId: {
type: mongoose.Schema.ObjectId,
required: true,
ref: 'User',
},
likedUserId: {
type: mongoose.Schema.ObjectId,
required: true,
ref: 'User',
},
isActive: {
type: Boolean,
required: true,
default: true,
},
},
{
timestamps: true,
}
);
После этого вы можете легко выполнить поиск по _id
:
const likedUsers = await UserLike.aggregate(
[
{
$group: {
_id: '$likedUserId',
likes: { $sum: 1 },
},
},
{ $sort: { likes: -1 } },
{
$lookup: {
from: 'users',
localField: '_id',
foreignField: '_id',
as: 'user',
},
}, {
$unwind: "$user"
}
]
);
В результате $lookup
вы получите массив user
, поэтому вам нужно использовать $unwind
для получения одного User
объекта.
Результат будет таким:
{
"_id": "604bb648be8680063009fddc",
"likes": 2,
"user": {
"_id": "604bb648be8680063009fddc",
"username": "muhamed",
"password": "$2b$10$EVYWZb4vl2TFGmIrCWe1sO/QogdU6/Ui8TgujY4PMKLJKIVOzmOi6",
"createdAt": "2021-03-12T18:43:20.806Z",
"updatedAt": "2021-03-12T18:46:17.635Z",
"__v": 0
},
}
Комментарии:
1. Большое вам спасибо, я не заметил идентификаторов в виде строки с тех пор, как скопировал их