首页 文章

mongodb - 查找与查询匹配的第一个子文档

提问于
浏览
0

我创建了一个非常类似于时间序列数据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'下的第一个子文档代表 year . 第二个子文档代表 month . 第三个子文档代表 day . 第四个子文档代表事件发生当天的 15 minute interval .

我想查询数据库,并在每天忽略所有后续条目时获得第一个真(并且可能是后面的假设,如果可能) .

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

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

谢谢您的帮助 .

2 回答

  • 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"
                }
            }
        }
    ])
    
  • 0

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

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

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

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

相关问题