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

Posted

技术标签:

【中文标题】带有日期字段的mongodb查询嵌套数组【英文标题】:mongodb query nested array with date field 【发布时间】:2019-09-29 15:56:07 【问题描述】:

这是我的文件。

"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
                    
                ]
            ,
   

这是我的shema:

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
                    
                
            ]
        
    ]
);

首先,您可以看到我的日历存储hotelIdCityId 并包含另一个包含一些对象的日历。这里没有什么花哨的。查询有以下两个条件:

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 
      
   
)  

【问题讨论】:

【参考方案1】:

不幸的是,这并不像您描述的那样容易,假设您只想投影(和所有)匹配的房间,这不能仅通过查找来完成。

但是,如果使用聚合,这是可能的,它看起来像这样:

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 的参数必须是一个数组,但类型:缺失” @tom-slabbaert 我有类似的文件和要求,您的查询非常有用,但 priceremaining 条件检查第一次约会房间,数据从 01/02/2019 到 05/ 02/2019 和 03/02/2019 的价格为 0,应该返回 false,但返回日历,但如果这发生在第一次日期 01/02/2019,条件有效。 @omid 对不起,我没听懂,你需要做同样的查询,但有细微的差别? @tomslabbaert 是的,请看这个问题,***.com/questions/56850607/…

以上是关于带有日期字段的mongodb查询嵌套数组的主要内容,如果未能解决你的问题,请参考以下文章

从Mongo DB嵌套数组中获取不同的值并输出到单个数组

MongoDB & Meteor - 推入嵌套数组的查询不起作用,没有抛出错误

mongodb查询更新选择嵌套字段

MongoDB:如何查询嵌套数组?

带有 C#Driver 的 MongoDB:如何过滤嵌套对象数组中的字段

带有 elemMatch 的 MongoDB 查询,用于从对象内部匹配嵌套数组数据 [重复]