我想返回一个给定shortName
的餐厅,并过滤其数组menuEntries
,使其仅包含将字段isAvailable
设置为true
的菜单项。
这是我的模式:
var restaurantSchema = new mongoose.Schema({
shortName: String,
fullName: String,
address: String,
logoImageUrl: String,
description: String,
location: {
type: { type: String },
coordinates: [Number]
},
menuEntries: [{
name: String,
description: String,
isAvailable: Boolean
}],
updatedAt: {type : Date}
});
restaurantSchema.index({ 'location': '2dsphere' });
mongoose.model('Restaurant', restaurantSchema, 'Restaurants');
我正在使用以下查询,但它仍返回将isAvailable
设置为false
的菜单项:
Restaurant
.findOne({
shortName: shortName,
menuEntries: { $elemMatch: { isAvailable: { $eq: true } } }
}, function(error, restaurant) {
if (error) {
returnJsonResponse(response, 500, {
'message': error
});
} else if (!restaurant) {
returnJsonResponse(response, 404, {
'message': 'Restaurant with name ' + shortName + ' doesn\'t exist'
});
} else {
returnJsonResponse(response, 200, restaurant);
}
});
编辑
它也不适用于以下代码:
Restaurant
.findOne({
shortName: shortName
})
.elemMatch('menuEntries', {'isAvailable': true})
.exec(function(error, restaurant) {
if (error) {
returnJsonResponse(response, 500, {
'message': error
});
} else if (!restaurant) {
returnJsonResponse(response, 404, {
'message': 'Restaurant with name ' + shortName + ' doesn\'t exist'
});
} else {
returnJsonResponse(response, 200, restaurant);
}
});
我正在使用猫鼬^ 5.6.2 和 MongoDB 3.6.9 。我在做什么错了?
答案 0 :(得分:0)
$elemMatch
不是您想要的。您尝试过滤文档内部的数组,而不是基于数组的文档列表。为了完成您想要实现的目标,您必须使用聚合和$filter
operator。
请查看the official example,但我认为您的代码应如下所示:
Restaurant.aggregate([
{
$project: {
menuEntries: {
$filter: {
input: "$menuEntries",
as: "entry",
cond: { $$eq: [ "$$entry.price", true ] }
}
},
shortName: 1,
fullName: 1,
address: 1,
logoImageUrl: 1,
description: 1,
location: 1,
updatedAt: 1
}
}
])
答案 1 :(得分:0)
viewRestaurant: (request, callback) => {
let aggrQuery = [
{
'$match': { "shortName": request }
},
{ $unwind: "$menuEntries" },
{ '$match': { 'menuEntries.isAvailable': true } },
]
restaurantQuery.aggregate(aggrQuery).exec((err, data) => {
if (err) {
callback(err, null)
}
else {
callback(null, data)
}
})
},
router.post('/view-restaurant',(req,res)=>{
var request = req.body.shortName;
restaurantController.viewRestaurant(request,(err,data)=>{
if(err) throw err;
res.json(data);
})
})