【问题标题】:mongodb - Find first subdocument that matches querymongodb - 查找与查询匹配的第一个子文档
【发布时间】:2018-08-20 23:43:49
【问题描述】:

我创建了一个与时间序列数据文档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
                        }
                    ]
                }
            }
        }
    }
}

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

我想每天查询数据库并获取第一个真值(如果可能的话,可能是紧随其后的假值),同时忽略所有后续条目。

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

如果您知道特定时间,这种结构非常适合查询特定时间,但我无法查询特定值。我应该只查询整个文档并在前端解析它吗?如果我想对数百个文档运行相同的查询,这将变得更加困难。

感谢您的帮助。

【问题讨论】:

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


    【解决方案1】:

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

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

    如果您卡在管道上,那么现在是返回一个新问题的好时机,该问题显示您到目前为止已设法编写的内容。在那之前,很遗憾,没有什么可以帮助您解决现有文档结构的问题了。

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

    【讨论】:

      【解决方案2】:

      要在单日上下文中分析您的数据,您必须使用一长串的$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"
                  }
              }
          }
      ])
      

      【讨论】:

      • 这太不可思议了。感谢您的帮助。
      猜你喜欢
      • 2019-05-06
      • 2013-06-24
      • 2017-08-21
      • 1970-01-01
      • 1970-01-01
      • 2020-11-17
      • 2014-03-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多