Arrays MongoDB获取嵌套在对象数组中的单个对象

Arrays MongoDB获取嵌套在对象数组中的单个对象,arrays,mongodb,mongoose,aggregation-framework,javascript-objects,Arrays,Mongodb,Mongoose,Aggregation Framework,Javascript Objects,如何基于几个属性值访问嵌套在另一个对象数组中的对象数组中的单个对象,如伪代码中所示: 选择日期=1,其中_id=5a3469f22dc3784bdd9a6190和月份=12 Mongoose模型模式如下所示。根据需要,子文档的列表高于相应的父文档,DailyScheduleSchema最高: var dailySchedulesSchema = new mongoose.Schema({ day: Number, dayStart: Number, firstBreakS

如何基于几个属性值访问嵌套在另一个对象数组中的对象数组中的单个对象,如伪代码中所示:

选择日期=1,其中_id=5a3469f22dc3784bdd9a6190和月份=12

Mongoose模型模式如下所示。根据需要,子文档的列表高于相应的父文档,DailyScheduleSchema最高:

var dailySchedulesSchema = new mongoose.Schema({
    day: Number,
    dayStart: Number,
    firstBreakStart: Number,
    firstBreakEnd: Number,
    lunchStart: Number,
    lunchEnd: Number,
    secondBreakStart: Number,
    secondBreakEnd: Number,
    dayEnd: Number,
    workDuration: Number
});

var monthlyScheduleSchema = new mongoose.Schema({
    month: {type: Number, required: true },
    dailySchedules: [dailySchedulesSchema]
});

var employeeSchema = new mongoose.Schema({
    name: {type: String, required: true},
    surname: {type: String, required: true},
    email: {type: String, required: true},
    phone: {type: String, required: true},
    occupation: {type: String, required: true},
    status: {type: Boolean, required: true},
    monthlySchedule: [monthlyScheduleSchema]
});
这是我试图处理的数据库中的员工条目:

"_id" : ObjectId("5a3469f22dc3784bdd9a6190"),
        "name" : "Eric",
        "surname" : "K. Farrell",
        "email" : "EricKFarrell@dayrep.com",
        "phone" : "864-506-7281",
        "occupation" : "Employee",
        "status" : true,
        "monthlySchedule" : [
                {
                        "month" : 12,
                        "dailySchedules" : [
                                {
                                        "day" : 1,
                                        "dayStart" : 480,
                                        "firstBreakStart" : 600,
                                        "firstBreakEnd" : 615,
                                        "lunchStart" : 720,
                                        "lunchEnd" : 750,
                                        "secondBreakStart" : 870,
                                        "secondBreakEnd" : 885,
                                        "dayEnd" : 1020,
                                        "workDuration" : 480
                                },
                                {
                                        "day" : 2,
                                        "dayStart" : 540,
                                        "firstBreakStart" : 630,
                                        "firstBreakEnd" : 645,
                                        "lunchStart" : 750,
                                        "lunchEnd" : 780,
                                        "secondBreakStart" : 870,
                                        "secondBreakEnd" : 885,
                                        "dayEnd" : 1050,
                                        "workDuration" : 480
                                }
                        ]
                }
        ]
}
获取单日的路径本身是:“/employeeid/:month/:day”

当我设法访问父文档(如列出所有员工)时,我无法列出特定的子文档条目(如该员工的特定日程安排)-mongoose已返回该月的所有现有日程安排,或者根本没有返回:

(……)

(……)


您可以尝试下面的聚合查询

下面的查询首先是
monthlySchedule
,它返回带有匹配月数组元素的数组,然后是第二个过滤器,用于检索
dailySchedules
数组中匹配的日元素

将包含单个元素的数组转换为文档

db.collection_name.aggregate([
  {"$match":{"_id":ObjectId("5a3469f22dc3784bdd9a6190")}},
  {"$project":{
    "dailyschedule":{
      "$arrayElemAt":[
        {"$filter":{
          "input":{
            "$filter":{
              "input":"$monthlySchedule",
              "cond":{"$eq":["$$this.month",12]}
            }
          },
          "cond":{"$eq":["$$this.day",1]
          }
        }},
      0]
    }
  }}
])
更新猫鼬代码:

Emp.aggregate([
  {"$match":{"_id":mongoose.Types.ObjectId(employeeid)}},
  {"$project":{
    "dailyschedule":{
      "$arrayElemAt":[
        {"$filter":{
          "input":{
            "$filter":{
              "input":"$monthlySchedule",
              "cond":{"$eq":["$$this.month",monthParam]}
            }
          },
          "cond":{"$eq":["$$this.day",dayParam]
          }
        }},
      0]
    }
  }}
])

您使用的是哪个版本我使用的是3.2.5版,但使用$ArrayElema时,您需要知道数组中的值的索引,而上面的示例似乎没有考虑到这一点,只关心它搜索的特定键值。老实说,这看起来是一个更实际的示例。索引为0的$arrayElemAt用于将匹配的日程安排(一个匹配项)转换为文档。如果没有arrayElemAt,则数组中的日程安排将匹配。如果愿意,您可以删除arrayElemAt$“放松”正是我使用arrayElemAt所做的,因为它总是输出一个每日日程匹配。因此,这里不需要$unwind。findOne方法除了返回整个dailySchedules数组外,似乎还可以很好地完成这项工作。有没有办法抑制其余的索引?Emp.findOne({u id:employeeid,“monthlySchedule.month”:monthParam,“monthlySchedule.dailySchedules.day”:dayParam})这就是为什么我们使用聚合,因为这无法使用常规查询语言完成。聚合代码是否不适用于您?它非常简单,首先根据month参数过滤monthlySchedule数组,然后根据day参数过滤daySchedule数组。如果您坚持在find query中执行此操作,那么您可以做的最好的事情是基于服务器的monthy param输出monthy schedule数组,并在day param上对day schedule进行客户端筛选。希望它有意义。请尝试
var monthParam=Number.parseInt(req.params.month)
并将其传递给聚合方法。如我的回答所示,不需要$REWIND。
db.collection_name.aggregate([
  {"$match":{"_id":ObjectId("5a3469f22dc3784bdd9a6190")}},
  {"$project":{
    "dailyschedule":{
      "$arrayElemAt":[
        {"$filter":{
          "input":{
            "$filter":{
              "input":"$monthlySchedule",
              "cond":{"$eq":["$$this.month",12]}
            }
          },
          "cond":{"$eq":["$$this.day",1]
          }
        }},
      0]
    }
  }}
])
Emp.aggregate([
  {"$match":{"_id":mongoose.Types.ObjectId(employeeid)}},
  {"$project":{
    "dailyschedule":{
      "$arrayElemAt":[
        {"$filter":{
          "input":{
            "$filter":{
              "input":"$monthlySchedule",
              "cond":{"$eq":["$$this.month",monthParam]}
            }
          },
          "cond":{"$eq":["$$this.day",dayParam]
          }
        }},
      0]
    }
  }}
])