#javascript #mongodb #aggregation-framework #aggregate
#javascript #mongodb #агрегация-фреймворк #агрегировать
Вопрос:
давайте рассмотрим, что у меня есть некоторая коллекция, и структуры данных выглядят следующим образом
почтовый индекс:
{
_id: ObjectId("5fce0e137ff7401634bad2ac")
address: "new york"
description: "this is a great city"
image: "images.4644859674390589-gikiguk.jpg"
userId: "5fcdcd8487e37216bc82171b"
}
номер пользователя:
{
_id: ObjectId("5fcdcd8487e37216bc82171b")
name: "jack"
profile: {image: "images.4644859674390589-dofowfg.jpg", description: "be happy dude"}
email: "test@test.com"
password: "2a$12$gzRrY83QAjwLhdyvn3JQ2OcMj3XG65.BULva4cZqcuSxDhhMbSXCq"
}
Лайки и комментарии col:
{
_id: ObjectId("5fce0e191ff7301666kao2xc")
likes: {quantity: 1, likes: [{isActive: true, userId: "5fcdcd8487c31216cc87886r"}]}
comments: {quantity: 1, comments: [{userId: "5fcdcd8487c31216cc87886r" , comment: "awesome city"}]}
postId: "5fce0e137ff7401634bad2ac"
}
что я хочу сделать, так это то, что у меня есть идентификатор пользователя (возможно, более одного), по которому я хочу выполнить поиск по всем сообщениям (которые принадлежат пользователю) и получить некоторые данные, posts collection
а затем $lookup
users collection
снова получить некоторые данные о пользователе, и после этого каждое сообщение имеет собственное postId
(я преобразовал _id
в postId
). с postId
помощью я могу $lookup
получить likeComments documents
и получить некоторые данные о любых сообщениях, но если у сообщения нет никаких лайков или комментариев, все мои запросы, которые я им написал, дают мне пустой массив []
(вообще не данные, а просто пустой массив), но если у сообщения есть хотя бы один лайк и один комментарий, все из моего запроса работает поиск.
то, что я ожидаю, это что-то вроде этого:
[
{
postId: '5fce0e137ff7401634bad2ac', //from post
location: 'shiraz', // from post
description: 'this is a greate city', // from post
image: 'images\0.4644859674390589-gikiguk.jpg', // from post
userId: '5fcdcd8487e37216bc82171b', // from user
name: 'mohammad', // from user
profile: 'images\0.6093033055735912-DSC_0002_2.JPG', // from user
comments: { quantity: 1, comments: [{userId: "...", name: "...", profile: "...", comment: "..."}] }, // from likesComments and then lookup to users documets to get data about users that wrote comments
likes: {quantity: 1, [{userId: "...", name: "...", profile: "..."}]} // from likesCommnets and then lookup to users documets to get data about users that liked the post
}
]
запрос:
я знаю, что мой запрос неверен, но я не могу найти, что здесь не так.
db.collection("posts")
.aggregate([
{ $match: { userId: { $in: users.map(u => u) } } },
{
$project: {
_id: 0,
userId: { $toObjectId: "$userId" },
postId: { $toString: "$_id" },
location: "$address",
description: "$description",
image: "$image"
}
},
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "userInfo"
}
},
{ $unwind: "$userInfo" },
{
$project: {
_id: 0,
postId: 1,
location: 1,
description: 1,
image: 1,
userId: { $toString: "$userId" },
name: "$userInfo.name",
profile: "$userInfo.profile.image"
}
},
{
$lookup: {
from: "likes-comments",
localField: "postId",
foreignField: "postId",
as: "likesComments"
}
},
{ $unwind: "$likesComments" },
{
$project: {
postId: 1,
location: 1,
description: 1,
image: 1,
userId: 1,
name: 1,
profile: 1,
likes: {
$map: {
input: "$likesComments.likes.likes",
as: "item",
in: {
$toObjectId: "$item.userId"
}
}
},
quantity: "$likesComments.comments.quantity",
comments: {
comments: {
$map: {
input: "$likesComments.comments.comments",
as: "item",
in: {
$toObjectId: "$item.userId"
}
}
}
}
}
},
{
$lookup: {
from: "users",
localField: "likes",
foreignField: "_id",
as: "likes"
}
},
{ $unwind: "$likes" },
{
$lookup: {
from: "users",
localField: "comments.comments",
foreignField: "_id",
as: "comments"
}
},
{ $unwind: "$comments" },
{ $addFields: { quantity: "$quantity" } },
{
$project: {
_id: 0,
postId: 1,
location: 1,
description: 1,
image: 1,
userId: 1,
name: 1,
profile: 1,
likes: [
{
userId: { $toString: "$likes._id" },
name: "$likes.name",
profile: "$likes.profile.image"
}
],
comments: {
quantity: 1,
comments: [
{
userId: { $toString: "$comments._id" },
name: "$comments.name",
profile: "$comments.profile.image"
}
]
}
}
}
])
.toArray();
Ответ №1:
В вашем примере есть несколько проблем:
- проверьте имена коллекций при поиске $. Существует множество несоответствий с названиями ваших коллекций.
- проверьте
types
иnames
поля $lookup. Некоторые идентификаторы находятся в строке, в то время как некоторые из них находятся в ObjectId. Это приведет к недопустимому поиску. Возможно, вам потребуется использовать вложенные запросы в $lookup для преобразования типов перед поиском. - Некоторые из ваших идентификаторов объектов содержат не шестнадцатеричные символы (например
_id
, oflikeComments
) - проблема с данными в примере; некоторые идентификаторы просто не совпадают. (например
likeComments.likes.likes.userId
, vsuser._id
)
Вот ПЕРВАЯ ПОЛОВИНА вашего конвейера с исправлениями части вышеуказанных проблем. Возможно, вы захотите использовать его в качестве ссылки для устранения оставшихся проблем.