【问题标题】:MongoDB: Aggregation query on nested arrayMongoDB:嵌套数组上的聚合查询
【发布时间】:2019-09-30 08:19:51
【问题描述】:

我现在正在研究实时开盘价-高-低-收盘价数据。我想找到每个库存商品的最高价和最低价的时间戳。

{   '_id': ObjectId('5d8db3700a1650f211831f16'),
    'isuLists': [   {   'hgprc': 8100,
                        'isuSrtCd': '000020',
                        'lwprc': 8100,
                        'opnprc': 8100,
                        'trdPrc': 8100},
                    {   'hgprc': 0,
                        'isuSrtCd': '000040',
                        'lwprc': 0,
                        'opnprc': 0,
                        'trdPrc': 500},
                    {   'hgprc': 10050,
                        'isuSrtCd': '000050',
                        'lwprc': 10050,
                        'opnprc': 10050,
                        'trdPrc': 10050},
                     ...
                     similar data continues
                     ...
                    {   'hgprc': 0,
                        'isuSrtCd': '700001',
                        'lwprc': 0,
                        'opnprc': 0,
                        'trdPrc': 9305},
                    {   'hgprc': 3310,
                        'isuSrtCd': '900140',
                        'lwprc': 3310,
                        'opnprc': 3310,
                        'trdPrc': 3310}],
    'trdDd': '20190927',
    'trdTm': '090000'
},
...
{   '_id': ObjectId('5d8d51000a1650f211826c9a'),
    'isuLists': [   {   'hgprc': 8130,
                        'isuSrtCd': '000020',
                        'lwprc': 7880,
                        'opnprc': 8100,
                        'trdPrc': 7980},
                    {   'hgprc': 508,
                        'isuSrtCd': '000040',
                        'lwprc': 498,
                        'opnprc': 504,
                        'trdPrc': 500},
                    {   'hgprc': 10050,
                        'isuSrtCd': '000050',
                        'lwprc': 9720,
                        'opnprc': 10050,
                        'trdPrc': 9780},
                     ...
                     similar data continues
                     ...
                    {   'hgprc': 0,
                        'isuSrtCd': '700001',
                        'lwprc': 0,
                        'opnprc': 0,
                        'trdPrc': 9305},
                    {   'hgprc': 3310,
                        'isuSrtCd': '900140',
                        'lwprc': 3230,
                        'opnprc': 3265,
                        'trdPrc': 3300}],
    'trdDd': '20190927',
    'trdTm': '155959'
}

数据从 9:00 到 16:00 每两秒累积一次(看看上面的trdTm)。

我设法使用下面的代码找出opnprcclsprc的时间戳,但找不到最高hgprc和最低lwprc的时间戳。

 [
    {"$unwind": "$isuLists"},
    {"$match": {"isuLists.lwprc": {'$gt': 0}}},
    {
        '$group': {
            '_id': '$isuLists.isuSrtCd',
            'opnTm': {'$first': '$trdTm'},
            'clsTm': {'$last': '$trdTm'}
        }
    }
]

我想为每个isuSrtCd(问题代码)找到最高hgprc和最低lwprctrdTm(交易时间)。

如何找到以下输出?

{issue code(isuSrtCd), timestamp(trdTm) of the highest 'hgprc', timestamp(trdTm) of the lowest 'lwprc'} 对于每个问题代码

[
   {'_id': '000020', 'hgTm': '110233', 'lwTm': '135205'},
   {'_id': '000040', 'hgTm': '142411', 'lwTm': '095233'},
   {'_id': '000050', 'hgTm': '110255', 'lwTm': '140017'},
   ...
   {'_id': '900140', 'hgTm': '105931', 'lwTm': '095329'},
]

感谢您的宝贵时间。

【问题讨论】:

    标签: mongodb nosql mongodb-query


    【解决方案1】:

    首先,highPrice 和 LowPrice 的时间可能不是唯一的。这意味着价格可能很高,并且对于许多积累来说可能是相同的。所以它本质上是数组。

    下面的查询实际上给了我 lowPrice 和 HighPrice 的最小值和最大值,同时它给了我 timeStamps 的数组——价格是低还是高。

     db.getCollection('trade').aggregate({"$unwind": "$isuLists"},
       {"$group":{
       "_id":"$isuLists.isuSrtCd",
       "minLowPrice":{$min:"$isuLists.lwprc"},
       "maxHighPrice":{$max:"$isuLists.hgprc"},
       "timeStamp":{"$push": 
       {date:"$trdDd",time:"$trdTm",highPrice:"$isuLists.hgprc",lowPrice:"$isuLists.lwprc"}}
       }},{"$project":
       {
       "sourceCode":"$_id",
       "lowPriceAndTime": { $filter:{input:"$timeStamp",as:"time",cond:{$eq: 
       ["$$time.lowPrice","$minLowPrice"]}}},
       "highPriceAndTime": { $filter:{input:"$timeStamp",as:"time",cond:{$eq: 
       ["$$time.highPrice","$maxHighPrice"]}}}
       }
    })
    

    【讨论】:

    • 我稍微修改了您的查询,它确实有效。虽然这个查询需要更多的内存和更多的时间,但我真的很感激 :)
    【解决方案2】:

    以下查询可以得到我们预期的输出:

    db.collection.aggregate([
        {
            $unwind:"$isuLists"
        },
        {
            $group:{
                "_id":"$isuLists.isuSrtCd",
                "min_stock":{
                    $min:{
                        "lwprc":"$isuLists.lwprc",
                        "trdTm":"$trdTm"
                    }
                },
                "max_stock":{
                    $max:{
                        "hgprc":"$isuLists.hgprc",
                        "trdTm":"$trdTm"
                    }
                }
            }
        },
        {
            $project:{
                "hgTm":"$max_stock.trdTm",
                "lwTm":"$min_stock.trdTm"
            }   
        }
    ]).pretty()
    

    数据集:

    {
        "_id" : ObjectId("5d8db3700a1650f211831f16"),
        "isuLists" : [
            {
                "hgprc" : 8100,
                "isuSrtCd" : "000020",
                "lwprc" : 8100,
                "opnprc" : 8100,
                "trdPrc" : 8100
            },
            {
                "hgprc" : 0,
                "isuSrtCd" : "000040",
                "lwprc" : 0,
                "opnprc" : 0,
                "trdPrc" : 500
            },
            {
                "hgprc" : 10050,
                "isuSrtCd" : "000050",
                "lwprc" : 10050,
                "opnprc" : 10050,
                "trdPrc" : 10050
            },
            {
                "hgprc" : 0,
                "isuSrtCd" : "700001",
                "lwprc" : 0,
                "opnprc" : 0,
                "trdPrc" : 9305
            },
            {
                "hgprc" : 3310,
                "isuSrtCd" : "900140",
                "lwprc" : 3310,
                "opnprc" : 3310,
                "trdPrc" : 3310
            }
        ],
        "trdDd" : "20190927",
        "trdTm" : "090000"
    }
    {
        "_id" : ObjectId("5d8d51000a1650f211826c9a"),
        "isuLists" : [
            {
                "hgprc" : 8130,
                "isuSrtCd" : "000020",
                "lwprc" : 7880,
                "opnprc" : 8100,
                "trdPrc" : 7980
            },
            {
                "hgprc" : 508,
                "isuSrtCd" : "000040",
                "lwprc" : 498,
                "opnprc" : 504,
                "trdPrc" : 500
            },
            {
                "hgprc" : 10050,
                "isuSrtCd" : "000050",
                "lwprc" : 9720,
                "opnprc" : 10050,
                "trdPrc" : 9780
            },
            {
                "hgprc" : 0,
                "isuSrtCd" : "700001",
                "lwprc" : 0,
                "opnprc" : 0,
                "trdPrc" : 9305
            },
            {
                "hgprc" : 3310,
                "isuSrtCd" : "900140",
                "lwprc" : 3230,
                "opnprc" : 3265,
                "trdPrc" : 3300
            }
        ],
        "trdDd" : "20190927",
        "trdTm" : "155959"
    }
    {
        "_id" : ObjectId("5d9331cef2e6411a68a145eb"),
        "isuLists" : [
            {
                "hgprc" : 8030,
                "isuSrtCd" : "000020",
                "lwprc" : 10,
                "opnprc" : 8100,
                "trdPrc" : 7980
            },
            {
                "hgprc" : 508,
                "isuSrtCd" : "000040",
                "lwprc" : 498,
                "opnprc" : 504,
                "trdPrc" : 500
            },
            {
                "hgprc" : 10050,
                "isuSrtCd" : "000050",
                "lwprc" : 9720,
                "opnprc" : 10050,
                "trdPrc" : 9780
            },
            {
                "hgprc" : 0,
                "isuSrtCd" : "700001",
                "lwprc" : 0,
                "opnprc" : 0,
                "trdPrc" : 9305
            },
            {
                "hgprc" : 3310,
                "isuSrtCd" : "900140",
                "lwprc" : 3230,
                "opnprc" : 3265,
                "trdPrc" : 3300
            }
        ],
        "trdDd" : "20190927",
        "trdTm" : "155960"
    }
    

    输出:

    { "_id" : "900140", "hgTm" : "155960", "lwTm" : "155959" }
    { "_id" : "000020", "hgTm" : "155959", "lwTm" : "155960" }
    { "_id" : "700001", "hgTm" : "155960", "lwTm" : "090000" }
    { "_id" : "000040", "hgTm" : "155960", "lwTm" : "090000" }
    { "_id" : "000050", "hgTm" : "155960", "lwTm" : "155959" }
    

    【讨论】:

    • 非常感谢!您的查询非常简单,而且效果非常好。
    • 哦,我意识到您的查询没有得到正确的 hgTm 和 lwTm...
    • @Mr.S.Sharma。您将价格和时间都传递给 $min 或 $max 所以它是'anding' time n price 然后给出
    • @Lucia 根据 MongoDB 文档比较规则,它会首先比较 lwprc,如果前面相同,则只比较 trdTm
    • 因此,如果最大hgprc 存在多次,则从这些中选择最大trdTm,如果最小lwprc 存在多次,则从这些中选择最小trdTm。 @SungpyoCho 不是你想要的吗?
    猜你喜欢
    • 1970-01-01
    • 2018-09-10
    • 2021-08-13
    • 1970-01-01
    • 2017-07-26
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多