【发布时间】:2018-06-06 18:52:23
【问题描述】:
我有一个像这样的 room 架构:
let roomSchema = new mongoose.Schema({
events: [{type: mongoose.Schema.ObjectId, ref: 'Event'}],
name: { type: String, required: true, index: { unique: true } }
});
它包含一个事件 ID 数组。 事件架构:
let eventSchema = new mongoose.Schema({
title: { type: String, required: true },
room: { type: mongoose.Schema.ObjectId, ref: 'Room', required: true },
date: { type: Date, required: true },
slot: { type: Number, required: true }
});
我想做的是:
"查询所有房间,不包含特定日期 AND slot的事件"。
因此,如果请求中的日期与房间和插槽的日期匹配,则该房间不应出现在响应中。如果只有一个字段匹配,则它应该在响应中。
我在这里找到了类似的问题,但没有针对我的场景:
https://stackoverflow.com/a/36371665/5115768
Mongoose query where value is not null
我尝试了类似的方法:
this.model.find(req.query).populate({
path: 'events',
match: {
date: { $ne: req.query.date },
slot: { $ne: req.query.slot }
}
}).exec((err, rooms) => {
rooms = rooms.filter((room) => {
return room.events != null;
});
res.status(200).json(rooms);
});
但当然它不起作用(房间总是空数组)。我很难弄清楚这一点。
如何查询具有基于子文档(事件)条件的文档(房间)?
更新
我更改了架构和代码,使 slot 不再是一个数组。
如果我正确理解了@Veeram 的解决方案,它就无法使用,因为它会为“预留房间”返回空的events 数组。这样做的问题是我需要用空的events 数组过滤掉这些房间,这将包括一开始没有关联任何事件的房间(这些不应该被过滤掉)。
现在我设法获得了所有“预订房间”(包含与 req.query.date 和 req.query.slot 匹配的事件的房间):
this.model.find(req.query).populate({
path: 'events',
match: {
$and: [
{ date: { $eq: date } },
{ slot: { $eq: slot } }
]
}
}).exec((err, reservedRooms) => {
reservedRooms = reservedRooms.filter(room => room.events.length > 0);
res.status(200).json(reservedRooms);
});
这与我想要的完全相反,但这是一个开始,我该如何“扭转”它?
【问题讨论】:
-
验证填充工作没有任何匹配,然后尝试
match: { date: { $ne: req.query.date }, slot: { $nin: [req.query.slot] } }。如果它有效,那么当没有匹配时它将输出一个空的事件数组,您可以根据对事件数组的空检查来过滤房间。 -
这有点帮助但不完全,请参阅我的 UPDATE
-
对不起,我不清楚,没有涵盖所有情况。对于不存在的事件,您在房间中不会有事件字段,因此那里没有可填充的内容,并且事件字段将不存在。对于存在的事件,它将根据您的匹配条件填充匹配事件。例如;
{room:"room1"}没有事件,{room:"room2", events:[]}没有匹配事件,{room:"room3", events:[{date:2017, title:"event1"]}匹配事件。所以基本上当你得到输出时,你只需要显示所有存在事件数组的房间。 -
或者,您可以将查询条件添加到 req.query 以仅考虑人口中存在的事件。像
{events:{$exists:true}}这样的东西。这样你得到的就是你的最终输出。 -
另一个选项如果您对事件数据不感兴趣并且只需要房间,您可以通过加入服务器端的事件集合来运行 $lookup 聚合查询并仅在输出响应中返回匹配的房间。
标签: javascript node.js mongodb mongoose mongodb-query