mongodb - 查找与查询

时间:2018-03-12 20:32:50

标签: node.js mongodb mongodb-query aggregation-framework

我创建了一个非常类似于时间序列数据here的文档的数据库模式。

我最终得到了以下文件:

{
    "_id" : "unique_name_1",
    "data" : {
        "2017" : {
            "5" : {
                "21" : {
                    "61" : [ 
                        {
                            "timestamp" : 1498162890460.0,
                            "value" : true
                        }
                    ],
                    "84" : [ 
                        {
                            "timestamp" : 1498183202126.0,
                            "value" : false
                        }
                    ]
                },
                "22" : {
                    "24" : [ 
                        {
                            "timestamp" : 1498215602957.0,
                            "value" : true
                        }
                    ],
                    "61" : [ 
                        {
                            "timestamp" : 1498249322863.0,
                            "value" : false
                        }
                    ]
                }
            },
            "9" : {
                "16" : {
                    "36" : [ 
                        {
                            "timestamp" : 1508249031987.0,
                            "value" : true
                        }, 
                        {
                            "timestamp" : 1508249429052.0,
                            "value" : false
                        }
                    ]
                }
            }
        }
    }
}

“data”下的第一个子文档代表。第二个子文档代表。第三个子文档代表。第四个子文档代表事件发生当天的 15分钟间隔

我希望每天查询数据库并获得第一个真值(如果可能的话,可能是后面的错误),同时忽略所有后续条目。

每天的第一个条目可能是也可能不是。数据不一定总是从true变为false返回true。例如,我可能连续有几个trues,在这种情况下,我想忽略所有后续的真值。

如果您了解特定时间,这个结构非常适合查询特定时间,但我对查询特定值感到茫然。我应该只查询整个文档并在前端解析它吗?如果我想在数百个文档上运行相同的查询,那就变得更加困难。

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

请注意,由于您使用的是键/值对而不是数组,因此您需要使用通配符键才能执行此类查询。这在MongoDB中根本不可能。

话虽如此,从版本3.6开始有一个名为$objectToArray的新聚合运算符,这可能对解决此问题很有用。我建议你在那里进行研究,并尝试开发适当的聚合管道。

如果你陷入困境,那么这将是一个回归的好时机,一个新的问题显示你到目前为止已经设法写了什么。在那之前,遗憾的是,为了帮助您解决现有的文档结构,可以做的更多。

当然,替代方案要么是要完全重组您的文件(核选项),如果您正在生产需要更新所有相关代码片段的生产系统,这可能不是可能的,或者直接在后端处理此数据,而不是通过MongoDB查询。

答案 1 :(得分:0)

要在一天的背景下分析您的数据,您必须使用一长串$objectToArray并结合$unwind。这是因为找出代表日,月,年的东西的唯一方法是分析嵌套的程度。但是,一旦你这样做,其余的可能很简单。尝试:

db.col.aggregate([
    {
        $project: {
            data: { $objectToArray: "$data" }
        }    
    },
    {
        $unwind: "$data"
    },
    {
        $project: {
            year: "$data.k",
            data: { $objectToArray: "$data.v" }
        }    
    },
    {
        $unwind: "$data"
    },
    {
        $project: {
            year: 1,
            month: "$data.k",
            data: { $objectToArray: "$data.v" }
        }    
    },
    {
        $unwind: "$data"
    },
    {
        $project: {
            year: 1,
            month: 1,
            day: "$data.k",
            data: { $objectToArray: "$data.v" }
        }    
    },
    {
        $unwind: "$data"
    },
    {
        $project: {
            year: 1,
            month: 1,
            day: 1,
            interval: "$data.k",
            data: "$data.v"
        }    
    },
    {
        $unwind: "$data"
    },
    {
        $match: { "data.value": true }
    },
    {
        $sort: {
            "data.timestamp": 1
        }
    },
    {
        $group: {
            _id: {
                year: "$year",
                month: "$month",
                day: "$day"
            },
            firstPositive: {
                $first: "$data"
            }
        }
    }
])
相关问题