带有日期字段的mongodb查询嵌套数组

带有日期字段的mongodb查询嵌套数组,mongodb,mongoose,mongoose-schema,Mongodb,Mongoose,Mongoose Schema,这是我的文件 "calendar": { "_id": "5cd26a886458720f7a66a3b8", "hotel": "5cd02fe495be1a4f48150447", "calendar": [ { "_id": "5cd26a886458720f7a66a413", "date": "1970-01-01T00:00:00.001Z",

这是我的文件

"calendar": {
        "_id": "5cd26a886458720f7a66a3b8",
        "hotel": "5cd02fe495be1a4f48150447",
        "calendar": [
            {
                "_id": "5cd26a886458720f7a66a413",
                "date": "1970-01-01T00:00:00.001Z",
                "rooms": [
                    {
                        "_id": "5cd26a886458720f7a66a415",
                        "room": "5cd17d82ca56fe43e24ae5d3",
                        "price": 10,
                        "remaining": 8,
                        "reserved": 0
                    },
                    {
                        "_id": "5cd26a886458720f7a66a414",
                        "room": "5cd17db6ca56fe43e24ae5d4",
                        "price": 12,
                        "remaining": 8,
                        "reserved": 0
                    },
                 {
                        "_id": "5cd26a886458720f7a66a34",
                        "room": "5cd17db6ca45fe43e24ae5e7",
                        "price": 0,
                        "remaining": 0,
                        "reserved": 0
                    }
                ]
            },
   }
这是我的谢玛:

const calendarSchema = mongoose.Schema({
    hotel: {
        type: mongoose.Schema.ObjectId,
        ref: "Hotel",
        required: true
    },
    city: {
        type: mongoose.Schema.ObjectId,
        ref: "City"
    },
    calendar: [
        {
            date: Date,
            rooms: [
                {
                    room: {
                        type: mongoose.Schema.ObjectId,
                        ref: "Room",
                        required: true
                    },
                    price: {
                        type: Number
                    },
                    remaining: {
                        type: Number
                    },
                    reserved: {
                        type: Number
                    }
                }
            ]
        }
    ]
});
首先,正如您所看到的,我的日历存储了
hotelId
CityId
,并包含了另一个包含一些对象的日历。这里没有什么新奇的东西。查询有两个条件,如下所示:

1.我们的特定筛选器位于startDate和endDate之间的整个日期

2.所述过滤器仅显示房间的价格和剩余价格(不包括零数)。

在注入这个条件之后,查询必须只返回与我的过滤器匹配的房间。 我尝试了一些查询,但结果不是我的结果

db.calendars.find({ 
  'calendar': { 
      '$elemMatch': { 
           date: { 
             '$lt': ISODate("2019-05-09T09:37:24.005Z"), 
             '$lt': ISODate("2019-06-05T09:37:24.005Z")
           },
           "rooms.$.price": { '$gt': 0 },
           "rooms.$.remaining": { '$gt': 0 }
      }
   }
})  

不幸的是,这并不像您描述的那么容易,如果您只想投影(和所有)匹配的房间,那么仅通过查找是无法做到的

但是,对于聚合,这是可能的,它将如下所示:

db.calendars.aggregate([
    {
        $project:
            {
                "rooms": {
                    $filter: {
                        input: {
                            "$map": {
                                "input": "$calendar",
                                "as": "cal",
                                "in": {
                                    "$cond": [
                                        {
                                            $and: [{$gt: ["$$cal.date", ISODate("2019-05-09T09:37:24.005Z")]},
                                                {$lt: ["$$cal.date", ISODate("2019-06-05T09:37:24.005Z")]},]
                                        },
                                        {
                                            "rooms": {
                                                "$filter": {
                                                    "input": "$$cal.rooms",
                                                    "as": "room",
                                                    "cond": {
                                                        $and: [{"$gt": ["$$room.price", 0]},
                                                            {"$gt": ["$$room.remaining", 0]}]
                                                    }
                                                }
                                            },
                                            date: "$$cal.date"
                                        },
                                        null
                                    ]
                                }
                            },
                        },
                        as: 'final',
                        cond: {$size: {$ifNull: ["$$final.rooms", []]}}
                    }
                },

            }
    },
    {
        $match: {
            "rooms.0": {$exists: true}
        }
    }
])

tnx对您的答案表示感谢,但它抱怨$size:“$size的参数必须是数组,但类型为:missing”@tom slabbaert我有一个类似的文档和要求,您的查询非常有用,但
price
剩余
条件检查第一个约会房间,在2019年2月1日至2019年2月5日的数据中,2019年2月3日的价格为0,应返回false,但返回日历,但如果在第一个日期
2019年2月1日
,条件有效。@omid很抱歉,我没有完全理解,您需要进行相同的查询,但有细微差异?@Tomslabaert是的,请查看此问题,