繁体   English   中英

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

[英]mongodb - Find first subdocument that matches query

我已经创建了一个数据库模式,该模式与此处的时间序列数据文档非常相似。

我得到了以下文件:

{
    "_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
                        }
                    ]
                }
            }
        }
    }
}

“数据”下的第一个子文档代表年份 第二个子文档代表月份 第三子文档表示日期 第四个子文档表示事件发生的当天的15分钟间隔

我想查询数据库并每天获取第一个为真(如果可能的话,可能会得到立即的假),而忽略所有后续条目。

每天的第一个条目可能正确也可能不正确。 数据并不一定总是从true到false再回到true。 例如,我可能连续有多个true,在这种情况下,我想忽略所有后续的true值。

如果您知道特定时间,此结构确实非常适合查询特定时间,但是我对于查询特定值不知所措。 我应该只查询整个文档并在前端进行解析吗? 如果要对数百个文档运行相同的查询,则变得更加困难。

谢谢您的帮助。

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

话虽如此,从3.6版开始有一个新的聚合运算符,称为$objectToArray ,它可能对解决此问题很有用。 我建议您在那里进行研究,并尝试在考虑该操作员的情况下开发适当的聚合管道。

如果您陷于流水线中,那么这将是返回一个新问题的好时机,该问题将显示您到目前为止已成功编写的内容。 不幸的是,在那之前,还不能做更多的事情来帮助您解决现有的文档结构。

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

要在单日情况下分析数据,必须使用一系列较长的$ 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"
            }
        }
    }
])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM