【问题标题】:MongoDB - Project specific element from array (big data)MongoDB - 数组中的项目特定元素(大数据)
【发布时间】:2018-02-21 00:37:29
【问题描述】:

我得到了一个包含以下格式数据的大数组:

{
  "application": "myapp",
  "buildSystem": {
    "counter": 2361.1,
    "hostname": "host.com",
    "jobName": "job_name",
    "label": "2361",
    "systemType": "sys"
  },
  "creationTime": 1517420374748,
  "id": "123",
  "stack": "OTHER",
  "testStatus": "PASSED",
  "testSuites": [
    {
      "errors": 0,
      "failures": 0,
      "hostname": "some_host",
      "properties": [

        {
          "name": "some_name",
          "value": "UnicodeLittle"
        },
        <MANY MORE PROPERTIES>,
        {
          "name": "sun",
          "value": ""
        }
      ],
      "skipped": 0,
      "systemError": "",
      "systemOut": "",
      "testCases": [
        {
          "classname": "IdTest",
          "name": "has correct representation",
          "status": "PASSED",
          "time": "0.001"
        },
        <MANY MORE TEST CASES>,
        {
          "classname": "IdTest",
          "name": "normalized values",
          "status": "PASSED",
          "time": "0.001"
        }
      ],
      "tests": 8,
      "time": 0.005,
      "timestamp": "2018-01-31T17:35:15",
      "title": "IdTest"
    }
      <MANY MORE TEST SUITES  >,
]}

我可以用大数据区分三个主要结构:TestSuites、Properties 和 TestCases。我的任务是对每个 TestSuite 的所有时间求和,以便获得测试的总持续时间。由于属性和 TestCases 很大,因此无法完成查询。我只想从 TestSuites 中选择“时间”值,但它与我的查询中的 TestCases 的“时间”有点冲突:

    db.my_tests.find(
        {
        application: application,
        creationTime:{
            $gte: start_date.valueOf(),
            $lte: end_date.valueOf()
        }
    },
    {
        application: 1, 
        creationTime: 1,
        buildSystem: 1,
        "testSuites.time": 1,
        _id:1
    }
   )

是否可以仅从 TestSuites 中投影“时间”属性而不加载整个架构?我已经尝试过 testSuites: 1, testSuites.$.time: 1 没有成功。请注意,TestSuites 是一个包含一个元素和字典的数组。

我已经检查过这个类似的帖子,但没有成功: Mongodb update the specific element from subarray

【问题讨论】:

标签: mongodb


【解决方案1】:

以下代码打印每个 TestSuite 的持续时间:

query = db.my_collection.aggregate(
    [
        {$match: {

            application: application,
            creationTime:{
                $gte: start_date.valueOf(),
                $lte: end_date.valueOf()
            }
        }
        },
        { $project :
            { duration: { $sum: "$testSuites.time"}}
        } 
    ] 
).forEach(function(doc) 
    {
        print(doc._id)
        print(doc.duration)
    }
)

【讨论】:

    【解决方案2】:

    是否可以仅从 TestSuites 投影“时间”属性 不加载整个架构?我已经尝试过 testSuites:1, testSuites.$.time

    回答您仅预测 testSuites 文档的 time 属性的问题,您可以简单地尝试使用 "testSuites.time" : 1 进行投影(您需要为点符号属性引用添加引号)。

    我的任务是对每个 TestSuite 的所有时间求和,以便获得 测试的总持续时间。由于属性和测试用例是 巨大,查询无法完成
    至于您的任务,我建议您尝试使用 mongodb 的聚合框架来进行计算文档转换。如果您正在处理“大型”文档,聚合框架选项 {allowDiskUse : true} 也会为您提供帮助。

    【讨论】:

    • 感谢您的回复,我对聚合查询进行了如下测试:db.my_collection.aggregate([ {$match: {creationTime:{ $gte: start_date.valueOf(),$lte: end_date. valueOf() }, application: application}}, { $project : {"testSuites.time" : 1 } } ])。它无法完成,这个查询在 Zeppelin 内部工作,所以如果我可以允许使用磁盘,那么 IDK 将遍历不同的应用程序,因此它实际上只需要选择必要的字段。如果 TestSuites 不是数组,我认为这个投影会起作用
    • 嗨,它确实有效,我之后执行的其他查询是断路器。我会批准你的回答,谢谢
    猜你喜欢
    • 2020-10-30
    • 2017-03-16
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 2023-03-21
    相关资源
    最近更新 更多