MongoDB聚合:计算数组元素或距离之间的差异

Posted

技术标签:

【中文标题】MongoDB聚合:计算数组元素或距离之间的差异【英文标题】:MongoDB Aggregation: Calculate differences between array elements or distances 【发布时间】:2019-09-08 11:17:48 【问题描述】:

在我的数据库中,我有一个对象在不同时间的位置。我想使用聚合来计算总行驶距离。

以下是数据示例。 “分钟”和“秒”字段提供位置的时间。 “位置”字段具有对象的 x 和 y 坐标。如何计算每两点之间的行进距离,然后求和总行进距离?

 
    "_id" : 0,
    "locations" : [ 
                     "minutes" : 43, "seconds" : 39,, "location" : [ 7.177781171570082, 8.39005423150688 ] ,
                     "minutes" : 43, "seconds" : 41, "location" : [ 13.239988410746804, 6.369708832879012 ] ,
                     "minutes" : 43, "seconds" : 51, "location" : [ 12.647876477258006, 6.288597609113424 ] ,
                     "minutes" : 43, "seconds" : 55, "location" : [ 12.662746868281697, 6.296370768057626 ] ,
                     "minutes" : 44, "seconds" : 38, "location" : [ 12.5326309468244, 6.308199488190107 ] ,
                     "minutes" : 44, "seconds" : 43, "location" : [ 12.53972817890389, 6.308199488190107 ] , 
                     "minutes" : 44, "seconds" : 53, "location" : [ 12.530265202797903, 6.310565232216604 ] , 
                     "minutes" : 44, "seconds" : 58, "location" : [ 12.527899458771406, 6.315296720269597 ] , 
                     "minutes" : 45, "seconds" : 31, "location" : [ 12.546825410983377, 6.315296720269597 ] ,
                     "minutes" : 45, "seconds" : 36, "location" : [ 12.542093922930384, 6.3129309762431 ] , 
                     "minutes" : 45, "seconds" : 45, "location" : [ 12.530265202797903, 6.3555143687200335 ] , 
                     "minutes" : 45, "seconds" : 40, "location" : [ 12.527899458771406, 6.341319904561056 ] , 
                     "minutes" : 45, "seconds" : 50, "location" : [ 12.536235756046255, 6.350367881600166 ] , 
                     "minutes" : 45, "seconds" : 59, "location" : [ 12.530265202797903, 6.327125440402078 ] , 
                     "minutes" : 45, "seconds" : 55, "location" : [ 12.546032231499275, 6.348017098292042 ] , 
                     "minutes" : 46, "seconds" : 14, "location" : [ 12.536573712767805, 6.3314498270318005 ] , 
                     "minutes" : 46, "seconds" : 18, "location" : [ 12.53972817890389, 6.3673430888525155 ] , 
                     "minutes" : 46, "seconds" : 23, "location" : [ 12.536525552897315, 6.364920756128036 ] , 
                     "minutes" : 46, "seconds" : 33, "location" : [ 11.969583868518272, 6.426486689514924 ]  
                ]


【问题讨论】:

$range? (docs.mongodb.com/manual/reference/operator/aggregation/range) 但我不知道,你将如何转换你的:Y,X 坐标点之间的距离, 【参考方案1】:

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

db.collection.aggregate([
    
        $project:
            "info":
                $reduce:
                    "input":
                        $slice:["$locations",1, $size:"$locations"]
                    ,
                    "initialValue":
                        "totalDistance":0,
                        "co-ordinates":
                            $let:
                                "vars":
                                    "firstLocation":
                                        $arrayElemAt:["$locations",0]
                                    
                                ,
                                "in":
                                    "x":
                                        $arrayElemAt:["$$firstLocation.location",0]
                                    ,
                                    "y":
                                        $arrayElemAt:["$$firstLocation.location",1]  
                                    
                                
                            
                        
                    ,
                    "in":
                        "totalDistance":
                            $sum:[
                                "$$value.totalDistance",
                                
                                    $sqrt:
                                        $sum:[
                                            
                                                $pow:[
                                                    
                                                        $subtract:[
                                                            
                                                               $arrayElemAt:["$$this.location",0] 
                                                            ,
                                                            "$$value.co-ordinates.x"
                                                        ]
                                                    ,
                                                    2
                                                ]
                                            ,
                                             
                                                $pow:[
                                                    
                                                        $subtract:[
                                                            
                                                               $arrayElemAt:["$$this.location",1] 
                                                            ,
                                                            "$$value.co-ordinates.y"
                                                        ]
                                                    ,
                                                    2
                                                ]
                                            
                                        ]
                                    
                                
                            ]
                        ,
                        "co-ordinates":
                            "x":
                                $arrayElemAt:["$$this.location",0] 
                            ,
                            "y":
                                $arrayElemAt:["$$this.location",1] 
                            
                        
                    
                
            

        
    ,
    
        $project:
            "_id":0,
            "totalDistance":"$info.totalDistance"
        
    
]).pretty()

数据集:


    "_id" : 0,
    "locations" : [
        
            "minutes" : 43,
            "seconds" : 39,
            "location" : [
                7.177781171570082,
                8.39005423150688
            ]
        ,
        
            "minutes" : 43,
            "seconds" : 41,
            "location" : [
                13.239988410746804,
                6.369708832879012
            ]
        ,
        
            "minutes" : 43,
            "seconds" : 51,
            "location" : [
                12.647876477258006,
                6.288597609113424
            ]
        ,
        
            "minutes" : 43,
            "seconds" : 55,
            "location" : [
                12.662746868281697,
                6.296370768057626
            ]
        ,
        
            "minutes" : 44,
            "seconds" : 38,
            "location" : [
                12.5326309468244,
                6.308199488190107
            ]
        ,
        
            "minutes" : 44,
            "seconds" : 43,
            "location" : [
                12.53972817890389,
                6.308199488190107
            ]
        ,
        
            "minutes" : 44,
            "seconds" : 53,
            "location" : [
                12.530265202797903,
                6.310565232216604
            ]
        ,
        
            "minutes" : 44,
            "seconds" : 58,
            "location" : [
                12.527899458771406,
                6.315296720269597
            ]
        ,
        
            "minutes" : 45,
            "seconds" : 31,
            "location" : [
                12.546825410983377,
                6.315296720269597
            ]
        ,
        
            "minutes" : 45,
            "seconds" : 36,
            "location" : [
                12.542093922930384,
                6.3129309762431
            ]
        ,
        
            "minutes" : 45,
            "seconds" : 45,
            "location" : [
                12.530265202797903,
                6.3555143687200335
            ]
        ,
        
            "minutes" : 45,
            "seconds" : 40,
            "location" : [
                12.527899458771406,
                6.341319904561056
            ]
        ,
        
            "minutes" : 45,
            "seconds" : 50,
            "location" : [
                12.536235756046255,
                6.350367881600166
            ]
        ,
        
            "minutes" : 45,
            "seconds" : 59,
            "location" : [
                12.530265202797903,
                6.327125440402078
            ]
        ,
        
            "minutes" : 45,
            "seconds" : 55,
            "location" : [
                12.546032231499275,
                6.348017098292042
            ]
        ,
        
            "minutes" : 46,
            "seconds" : 14,
            "location" : [
                12.536573712767805,
                6.3314498270318005
            ]
        ,
        
            "minutes" : 46,
            "seconds" : 18,
            "location" : [
                12.53972817890389,
                6.3673430888525155
            ]
        ,
        
            "minutes" : 46,
            "seconds" : 23,
            "location" : [
                12.536525552897315,
                6.364920756128036
            ]
        ,
        
            "minutes" : 46,
            "seconds" : 33,
            "location" : [
                11.969583868518272,
                6.426486689514924
            ]
        
    ]

输出:

 "totalDistance" : 7.931893594924767 

解释:我们使用$reduce 来总结每个点之间的行进距离。两点之间的距离使用以下公式计算 公式:

           _______________________
Distance: √(x2−x1)^2 + (y2−y1)^2

【讨论】:

以上是关于MongoDB聚合:计算数组元素或距离之间的差异的主要内容,如果未能解决你的问题,请参考以下文章

计算圆形数组中元素之间的距离

Mongodb聚合:投影没有最后一个元素的数组

MongoDB:使用正则表达式聚合数组元素

信号处理 - 熵

MongoDB 实用数组聚合操作 (2)

MongoDB聚合,如何在组管道中addToSet数组的每个元素