Я использую почти чистый JS-код для объединения трех коллекций в MongoDB, и я считаю, что должен быть более простой способ сделать это, используя простой запрос мангуста.
Вот мой случай; У меня есть продавец, который может создавать и продавать документы. Я хочу, чтобы мой продавец мог видеть проданные им документы.
Это моя схема для коллекции заказов:
const OrderSchema = new mongoose.Schema({
//...
user: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: true
},
documents: [
{
document: {
type: mongoose.Schema.ObjectId,
ref: 'Document',
required: true
},
price: {
type: Number,
required: [true, 'Price is required']
}
}
],
//...
});и моя схема документа выглядит так:
const DocumentSchema = new mongoose.Schema({
//...
title: {
type: String,
required: [true, 'Please provide a title'],
},
author: {
type: mongoose.Schema.ObjectId,
ref: 'Seller',
required: true
},
//...
});Как я сказал ранее, я хочу получить список документов, принадлежащих продавцу, который был продан, вошедшим в систему. (Что-то вроде этого).
"data": [
{
"orderId": "606b448dd2d9d643a811bc33",
"documentId": "606b448dd2d9d643a811bc34",
"title": "Document 1 u1",
"price": 90,
"createdAt": "2021-04-05T17:10:37.469Z"
},
{
"orderId": "606b43d2cd9b2740b8b8974b",
"documentId": "606b43d2cd9b2740b8b8974c",
"title": "Business Affiliate u7",
"price": 222,
"createdAt": "2021-04-05T17:07:30.859Z"
},
{
"orderId": "606b1a03ec048e0d44cb3bee",
"documentId": "606b1a03ec048e0d44cb3bef",
"title": "Business Affiliate u7",
"price": 777,
"createdAt": "2021-04-05T14:09:07.539Z"
},
{
"orderId": "606b1a03ec048e0d44cb3bee",
"documentId": "606b1a03ec048e0d44cb3bf0",
"title": "Doc 1 u1",
"price": 1,
"createdAt": "2021-04-05T14:09:07.539Z"
},
]Код, который я получил, приведен ниже. Он выглядит некрасиво и содержит три форса.
const documents = await Document.find().where('author', req.uid).select('orders').populate({ path: 'orders' })
let filteredOrders = [];
for (const document of documents) {
//GET ALL ORDERS THAT CONTAINS THIS DOCUMENTS
const orders = await Order.find().where('documents.document', document._id).populate({ path: 'documents.document', select: 'title' }).sort('-createdAt');
for (const order of orders) {
for (const doc of order.documents) {
if (doc.document._id.toString() == document._id.toString()) {
filteredOrders.push({
orderId: order._id,
documentId: doc._id,
title: doc.document.title,
price: doc.price,
createdAt: order.createdAt
});
}
}
}
}
filteredOrders.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
res.status(200).json({ success: true, data: filteredOrders });Есть ли способ получить тот же результат, используя только Mongoose?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


После некоторого исследования и чтения документации (20 вкладок) это окончательный код (может потребоваться некоторая очистка):
let id = mongoose.Types.ObjectId(req.uid);
const orders = await Order
.aggregate([
{ $unwind: '$documents' },
{
$lookup: {
from: "documents",
localField: "documents.document",
foreignField: "_id",
as: "document"
}
},
{ $match: { 'document.author': id } },
{ $project: { user: 1, deliveryEmail: 1, createdAt: 1, documentTitle: '$document.title', documentId: '$documents.document', documentPrice: '$documents.price' } },
{ $sort: { 'createdAt': -1 } }
])
res.status(200).json({ success: true, data: orders });