使用Mongoose(甚至只是MongoDB查询),我想返回一个匹配所有文档的查询结果:
a)"单位" field(子文档数组)包含一个带有" unit"的子文档。 field,它本身包含一个带有" _id"的子文档。匹配给定字符串值的字段
b)"单位"字段包含一个带有"句点"的子文档。 field(Date对象的数组),其中给定日期位于数组中的第一个和第二个元素之间。
数据结构如下所示:
{
"_id" : ObjectId("5984bdfdb3ac279e39f156d4"),
"surname" : "Dare",
"firstname" : "Dan",
"units" : [{
"period" : [
ISODate("2018-01-01T00:00:00.000Z"),
ISODate("2019-12-31T00:00:00.000Z")
],
"unit" : {
"unit_name" : "My test unit",
"_id" : "5979437c6d346eb7d074497a"
}
}]
}
我尝试过使用.find()和.aggregate()的各种组合,例如在句点数组上使用$ project和$ filter,在unit._id上使用$ elemMatch,但无济于事 - 我得到错误,例如"不能在数组"上使用$ filter。
任何正确方向的指针都会受到赞赏 - 至少在最合适的查询类型和最有效的方法来组合运算符以生成我之后的数据集。
架构(根据要求):
{
surname: {
type: String
},
firstname: {
type: String
},
units: {
type: [{
unit: {
_id: String,
unit_name: String,
},
period: [Date]
}]
}
}
答案 0 :(得分:1)
认为我的问题太复杂了。不确定这是否是最有效的方法,但使用$和运算符似乎提供了我正在寻找的东西:
db.getCollection("records").find({ "$and": [
{"units.unit._id": "5979437c6d346eb7d074497a"},
{"units.unit_period.0": {"$gte": new Date('2018-12-31T00:00:00.000Z')} },
{"units.unit_period.1": {"$lte": new Date('2020-12-31T00:00:00.000Z')} } ]
})
根据Neil Lunn在评论中提出的建议,使用$ elemMatch而不是$,由于给出的理由,肯定是更好的选择。
因此,这是我应该采用的解决方案;即使用#emMmMatch匹配那些包含嵌入式子文档和数组的元素,其中可以通过键上的简单点符号访问和匹配值。
我尝试使用$ filter和$ aggregate过度编写解决方案,但是在检索我需要的数据集时实际上就像这样简单:
db.getCollection("records").find({ "units":
{ "$elemMatch":
{ "unit._id": "5979437c6d346eb7d074497a",
"unit_period.0": { "$gte": new Date('2019-12-31") },
"unit_period.1": { "$lte": new Date("2020-12-31") }
}
})