#mongodb #express #mongodb-query
#mongodb #выразить #mongodb-запрос
Вопрос:
Я новичок в MongoDB и Express JS
У меня есть модель продукта, которая выглядит как
const productSchema = mongoose.Schema({
name: String,
title: String,
brand_id: { type: mongoose.Schema.Types.ObjectId, ref: 'brand' },
varient:[{
country_id: { type: mongoose.Schema.Types.ObjectId,ref: 'countries'},
max_retail_price : Number,
profit_margin : Number
}],
и модель упорядочения
const orderTransactionSchema = mongoose.Schema({
shop_id: { type: mongoose.Schema.Types.ObjectId, ref: 'shop' },
brand_id:{ type: mongoose.Schema.Types.ObjectId, ref: 'brand' },
product_id: { type: mongoose.Schema.Types.ObjectId, ref: 'product' },
product_varient_id:{ type: mongoose.Schema.Types.ObjectId, ref: 'product.varient._id' },
transaction_id:{ type: mongoose.Schema.Types.ObjectId, ref: 'transaction' }
})
module.exports = mongoose.model('order', orderTransactionSchema );
В моей коллекции продуктов каждый продукт может иметь несколько вариантов.
Но при сборе заказов пользователь может заказать только один вариант продукта в разделе «продукт».
Я пытаюсь отобразить заказы с конкретными деталями продукта и деталями варианта, но проблема в том, что когда я пытаюсь отобразить его с помощью заполнения / агрегирования, я получаю все варианты в массиве ответов. на самом деле, мне нужны только сведения об одном продукте и варианте, как в коллекции заказов.
Это то, что я пробовал
order.aggregate([{ $match :{} },
{
$lookup: {
from: "products",
localField: "product_id",
foreignField: "_id",
as: "product_data"
}
},
]).exec(function(err,result){
console.log(result);
});
и я получаю результат в виде
{ _id: 5c8a010b8feeb875abc1b066,
shop_id: 5c7d194ca10ea45c0c03a0ee,
brand_id: 5c41a8c34272c61a176b7639,
product_varient_id: 5c41a9f3f8e1e71aa75b4f32,
transaction_id: 5c6670d5b6c63d0762c6cc77,
product_id: 5c41aac4d45a731af564c433,
product_data:
[ { _id: 5c41aac4d45a731af564c433,
brand_id: 5c41a8c34272c61a176b7639,
image: 'test.jpg',
varient: //getting all the varients here
[ { _id: 5c4ee531bc20b27948b3aa98,
sell_rate_local: 66,
country_id: 5c01149d3c20440a6b2e4928 },
{ _id: 5c4ee53bbc20b27948b3aa99,
sell_rate_local: 66,
country_id: 5c00e1697dd7a23f08bdae68 } ],
__v: 0 } ] } ]
В таблице заказов есть porduct_id и есть product_varient_id
Я хочу заполнить только продукт с помощью product_varient_id.
Я также пробовал что-то с Populate
order.find().
populate([
{ path: 'shop_id', model: 'shop',select : 'name accounts' }, //it works
{ path: 'transaction_id', model: 'transaction' }, //it wrks
{ path: 'product_varient_id', model: 'product', select:'product.varient.name'},
]).then(result =>
{
// console.log(result);
}).catch(err =>{
// console.log(err);
});
Это образец документа о продукте и заказе
Образец документа заказа :
{
"_id":"5c77a025d65a892f6acf1803",
"shop_id":"5c7d194ca10ea45c0c03a0ee",
"brand_id":"5c41a8b44272c61a176b7638",
"product_varient_id":"5c41a9f3f8e1e71aa75b4f32",
"buy_rate":10,
"buy_rate_after_discount":20,
"product_mrp":30,
"sell_rate":40,
"customer_mobile":123456789,
"status":true,
"transaction_id":"5c6670c9b6c63d0762c6cc76",
"product_id":"5c41a95ff8e1e71aa75b4f30",
"createdAt":"2019-02-28T08:47:33.097Z",
"updatedAt":"2019-02-28T08:47:33.097Z",
"__v":0
}
Образец документа продукта :
{
"_id":"5c41aac4d45a731af564c433",
"recharge_type":[
"5c00d9cf7dd7a23f08bdae5e"
],
"name":"25 OC - Product 1",
"title":"First installation recharge",
"description":"0.1 credit for first time installation",
"offer_message":"Hi.. You got 0.1 credits..!!",
"brand_id":"5c41a8c34272c61a176b7639",
"buy_rate":20,
"profit_margin":80,
"image":"test.jpg",
"varient":[
{
"_id":"5c4ee531bc20b27948b3aa98",
"display_name":"testlia",
"profit_margin":66,
"max_retail_price":66,
"sell_rate":66,
"sell_rate_local":66,
"country_id":"5c01149d3c20440a6b2e4928"
},
{
"_id":"5c4ee53bbc20b27948b3aa99",
"display_name":"testrinu",
"profit_margin":66,
"max_retail_price":66,
"sell_rate":66,
"sell_rate_local":66,
"country_id":"5c00e1697dd7a23f08bdae68"
}
],
"createdAt":"2019-01-18T10:30:28.991Z",
"updatedAt":"2019-01-28T11:19:23.662Z",
"__v":0
}
Комментарии:
1. Не могли бы вы опубликовать образцы документов из всех коллекций
2. @Anthony Winzlet Я уже добавил пример вывода, который я получаю из запроса. Основная проблема связана с коллекцией ‘product’ . В коллекции продуктов у меня есть другой документ. Это означает, что у одного продукта может быть несколько вариантов. Но в суммированном заказе есть только один вариант продукта purslchse. Поэтому я не могу заполнить только определенный идентификатор варианта, соответствующий этому заказу продукта.
3. @Anthony Winzlet не могли бы вы ответить, пожалуйста…
4. Если бы вы могли показать несколько образцов документов и желаемый результат, тогда только я могу вам помочь.
5. @Anthony Winzlet Я обновлю вопрос
Ответ №1:
MongoDB 3.6 или выше имеют новый синтаксис поиска
db.orders.aggregate([{
$lookup: {
from: "products",
let: {
"productId": "$product_id",
"productVarientId": "$product_varient_id"
},
pipeline: [
{ $match: {
$expr: { $eq: [ "$_id", "$$productId" ]}
}
},
{ $addFields: {
varient: {
$filter: {
input: "$varient",
as: "varient",
cond: { $eq: [ "$$productVarientId", "$$varient._id" ] }
}
}
}
}
],
as: "product_data"
}
}])
Вы можете проверить образец данных здесь
Комментарии:
1. Мне нужно поместить условие внутри match , но мне нужно проверить условие match только в том случае, если массив condition не пуст
2. @Anthony Winzlet можешь ответить?
3. @Sibinfrancis не могли бы вы подробнее изложить свою точку зрения, показать, что я могу в этом помочь? как я вижу, если вы хотите соответствовать условию, вы можете использовать его на первом этапе агрегирования. Если вы хотите изменить выходные данные. пожалуйста, поделитесь образцами данных.