【发布时间】:2021-02-06 03:38:31
【问题描述】:
首先,我有这种类型的模型:
const produkSchema = new mongoose.Schema({
nama_produk: String,
etalase: {type: mongoose.Schema.Types.ObjectID, ref: 'kategori'},
kategori: {type: mongoose.Schema.Types.ObjectID, ref: 'kategori'},
jenis: {type: mongoose.Schema.Types.ObjectID, ref: 'kategori.jenis'},
bahan: String,
warna: String,
deskripsi: String,
foto_produk: [String],
harga: Number,
link_bukalapak: String,
link_shopee: String,
link_tokopedia: String,
link_lazada: String,
link_website: String,
display: {type: Boolean, default: false},
}, {
weights: {
nama_produk: 5,
},
timestamps: true
})
const tokoSchema = new mongoose.Schema({
username: {type: String, trim: true},
password: {type: String, required: true, select: false},
merek: String,
listMerek: [{type: mongoose.Schema.Types.ObjectID, ref: 'produk'}],
deskripsi: String,
follower: [{type: mongoose.Schema.Types.ObjectID, ref: 'user'}],
email: {type: String, trim: true, unique: true},
instagram: String,
whatsapp: String,
website: String,
alamat: String,
foto_profil: String,
bukalapak: String,
shopee: String,
tokopedia: String,
fotoktp: String,
banner: [{
gambar: {type: String, required: true, trim: true},
// order: {type: Number, required: true},
}],
produk: [produkSchema],
etalase: [{type: mongoose.Schema.Types.ObjectID, ref: 'kategori'}],
// etalase: [{
// kategori: {type: mongoose.Schema.Types.ObjectID, ref: 'kategori'},
// order: {Number}
// }],
approve: {type: Number, default: 0}, // 0: pending, 1: reject, 2: approve
populer: {type: Boolean, default: false},
gambar_populer: [String],
pilihan: {type: Boolean, default: false},
}, {timestamps: true});
我有一个端点可以使用以下代码过滤此produkSchema:
exports.filterProduk = (req, res) => {
const {merek, warna, kategori, jenis, hargaAwal, hargaAkhir, skip, limit} = req.body
let query = {}
const $and = []
if (merek) {
$and.push({$or: merek.map(id => ({_id: mongoose.Types.ObjectId(id)}))})
}
if (warna) {
$and.push({$or: warna.map(warna => ({"produk.warna": warna}))})
}
if (kategori) {
query["produk.etalase"] = mongoose.Types.ObjectId(kategori)
}
if (jenis) {
$and.push({$or: jenis.map(id => ({"produk.jenis": mongoose.Types.ObjectId(id)}))})
}
if (hargaAwal !== '') {
query["produk.harga"] = {
$gte: parseInt(hargaAwal),
}
}
if (hargaAkhir !== '') {
query["produk.harga"] = {
$lte: parseInt(hargaAkhir)
}
}
if ($and.length > 0) {
query = {$and, ...query}
}
toko.aggregate([
{$unwind: '$produk'},
{$match: query},
{
$lookup: {
from: "kategoris",
as: "produk.etalase",
let: {pjid: "$produk.jenis"},
pipeline: [
{$unwind: "$jenis"},
{$match: {$expr: {$eq: ["$$pjid", "$jenis._id"]}}},
{
$project: {
"jenis._id": 1,
"jenis.label": 1
}
}
]
}
},
{$unwind: {path: "$produk.etalase"}},
{$group: {_id: '$_id', produk: {$push: '$produk'}, foto_profil: {$first: '$foto_profil'}}},
{$limit: skip + limit},
{$skip: skip}
])
.then(async data => {
res.status(200).json({data, prefix: {produk: "uploads/produk", toko: "uploads/toko"}})
})
}
实际结果是:
[
{_id: blabla,
foto_profil: "blabla",
produk:[{nama_produk: "blabla", bahan: "blabla", ...rest ProdukSchema as query}]
},
{_id: blabla,
foto_profil: "blabla",
produk:[{nama_produk: "blabla", bahan: "blabla", ...rest ProdukSchema as query}]
},
{_id: blabla,
foto_profil: "blabla",
produk:[{nama_produk: "blabla", bahan: "blabla", ...rest ProdukSchema as query}]
}
]
预期:
[
{nama_produk: "blabla", bahan: "blabla", ...rest ProdukSchema as query, foto_profil(from toko schema): "blabla"},
{nama_produk: "blabla", bahan: "blabla", ...rest ProdukSchema as query, foto_profil(from toko schema): "blabla"}
]
并使用此produkSchema 进行分页(限制和偏移)
其实在此之前,我已经在here求过这个查询,但是这个查询会产生很多数据,需要分页,
我该怎么做?我应该将我的produkSchema 拆分为主子文档吗?或者是否存在针对这种情况的任何查询?
【问题讨论】:
-
@turivishal 非常好!两个 Playground 都与我的预期输出相同,但我需要此查询的跳过和限制,你能更新 Playground 吗?
标签: mongodb mongoose mongodb-query aggregation-framework mongoose-schema