这可能是一个愚蠢的问题,但是我对MongoDB还是陌生的,所以让我们尝试一下。
我正在MongoDB上创建一个数据库,该数据库将存储每五分钟输入一次的输入。该数据库采用SQL格式,应返回如下内容:
主要问题在这里,我不知道是否应该为每个idvar创建一个文档,其中包含每年/每月/每天的条目,如果我将JSON设置为类似的格式,会损害性能吗?
{
"_id" : ObjectId("xxxxxxxxxxxxxxxxxxxx"),
"IdVar" : "60502",
"Years" : [
{
"2015" : [
{
"January" : [
{
"Date_Start" : "2015-01-01",
"Date_End" : "2015-01-02"
}
],
"February" : [
{
"Date_Start" : "2015-01-01",
"Date_End" : "2015-01-02"
}
]
}
]
}
]
}
答案 0 :(得分:3)
首先,嵌套数组查询总是很乏味。
请考虑以下集合(如拟议的in the comments of this post):
[
{
"IdVar": "60502",
"dates": [
{
"start": new Date("2017-03-01"),
"end": new Date("2017-04-01")
},
{
"start": new Date("2018-04-01"),
"end": new Date("2018-06-01")
}
]
},
{
"IdVar": "1337",
"dates": [
{
"start": new Date("2016-08-01"),
"end": new Date("2016-09-01")
},
{
"start": new Date("2015-04-01"),
"end": new Date("2015-06-01")
}
]
}
]
您只想检索日期为2017年的文档。您可以使用$elemMatch
运算符来这样做:
db.collection.find({
dates: {
$elemMatch: {
start: {
$gte: ISODate("2017-01-01T00:00:00Z"),
$lte: ISODate("2017-12-31T00:00:00Z")
}
}
}
})
...但是,正如您正确地指出的那样,这将使您完整无损地返回文档。在许多情况下,这很适合您的需求,因为您可能仍想根据您的查询来投影您的文档字段:一种简单的表达方式是说投影是与SELECT
和查询WHERE
等效的SQL。
作为示例,以下内容将只返回与我的查询匹配的每个文档的IdVar
字段:
db.collection.find({
dates: {
$elemMatch: {
start: {
$gte: ISODate("2017-01-01T00:00:00Z"),
$lte: ISODate("2017-12-31T00:00:00Z")
}
}
}
},
// Project your document's fields here:
{
IdVar: true
})
...将返回:
[
{
"IdVar": "60502",
"_id": ObjectId("5a934e000102030405000000")
}
]
与查询类似,您可以(几乎)在投影字段中使用所有Mongo运算符。
$
运算符在处理嵌套数组时也非常方便。以下代码将返回您所需的内容,并尝试一下(MongoPlayground):
db.collection.find({
dates: {
$elemMatch: {
start: {
$gte: ISODate("2017-01-01T00:00:00Z"),
$lte: ISODate("2017-12-31T00:00:00Z")
}
}
}
},
{
"dates.$": 1
})