MongoDB查询:如何查找嵌套对象中的字符串

hyrbngr7  于 2023-08-04  发布在  Go
关注(0)|答案(1)|浏览(106)

我有以下带有attendance字段的Course Schema,其中存储了具有以下键值结构(字符串:具体地,attendance对象的键存储上课的日期,而值存储出席的学生的列表(学生ID)。

var CourseSchema = new Schema({
  attendance: {},
});

字符串
例如,单个课程项目可以如下所示:

{"_id":"559a7353186a384b54f9aea9","attendance":{"2015-12-17":["558febdb949eff4711e621e9","559020fe79f141941ddd3246"],"2015-11-14":["558febdb949eff4711e621e9","559020fe79f141941ddd3246"]}


我试图返回有学生参加过的课程(所以基本上返回在其出勤字段中包含特定学生ID的任何课程)。我试着这样做,但它返回空结果。我的查询有什么问题吗?
我试着检查这个链接,但它不适合我太多。MongoDB query inside a nested array

Course.find({"attendance.$": {$in: ["558febdb949eff4711e621e9"]}}...)

vhipe2zx

vhipe2zx1#

解决方案是合理的,但是您的模式在这里出错了。在这样的数据库中使用“命名键”存在很大的问题,您应该将它们视为“属性”。
例如:

{
    "_id" : ObjectId("559a7353186a384b54f9aea9"),
    "attendance" : [
            {
                    "date" : ISODate("2015-12-17T00:00:00Z"),
                    "student" : ObjectId("558febdb949eff4711e621e9")
            },
            {
                    "date" : ISODate("2015-12-17T00:00:00Z"),
                    "student" : ObjectId("559020fe79f141941ddd3246")
            },
            {
                    "date" : ISODate("2015-11-14T00:00:00Z"),
                    "student" : ObjectId("558febdb949eff4711e621e9")
            },
            {
                    "date" : ISODate("2015-11-14T00:00:00Z"),
                    "student" : ObjectId("559020fe79f141941ddd3246")
            }
    ]
}

字符串
它在模式中定义为:

AttendanceSchmema = new Schema({
  "date": Date,
  "student": { "type": Schema.Types.ObjectId, "ref": "Student" }
},{ "_id": false });

CourseSchema = new Schema({
  "attendance": [AttendanceSchema]
});


然后我可以简单地匹配给定的学生:

Course.find(
  { "attendance.student": "559020fe79f141941ddd3246" },
  { "attendance.$": 1 }
)


甚至是一个学生在给定的日期:

Course.find(
  { "attendance": { 
     "$elemMatch": { 
       "student": "559020fe79f141941ddd3246",
       "date": { "$gte": new Date("2015-12-15"), "$lt": new Date("2015-12-16") }
     }
  }},
  { "attendance.$": 1 }
)


甚至更多的可能性。我们将所有这些放在一个具有类似于属性的“attribute”的数组中的原因是为了使查询和存储变得简单。
如果没有这样的改变,你会被执行糟糕的查询所困,比如:

Course.find({ "$where": function() {
  return Object.keys(this.attendance).some(function(k) {
    return this.attendance[k].indexOf("558febdb949eff4711e621e9") > -1
  });
}})


当然,假设这些值目前是“字符串”,因为它们看起来是Mixed类型。
更糟糕的是,对于任何更复杂的查询,它也不能告诉你哪个位置匹配。但到目前为止最糟糕的事情是这些不可能使用一个“索引”来匹配。
因此,您确实应该考虑将这里的数据库模式更改为一种将以最有效的方式支持查询的形式。

相关问题