使用MongoDB查找最相似的数组

时间:2019-10-03 22:09:33

标签: arrays node.js mongodb aggregation-framework

我正在尝试使用MongoDB查询找到数字数组之间的最小距离。我的技术堆栈是带有MongoDB 4的Node.js + Mongoose。

这是我们的输入数组A:

A = [1, 2, 3, 4, 5]

并存储在MongoDB中,我们有这样的对象:

[
  {
    id: 0
    nums: [4, 5, 6, 7, 8]
  },
  {
    id: 1
    nums: [-500, 50.2, 60, 74, 1]
  },
  {
    id: 2
    nums: [9, 5, 32, -7, 5]
  }
]

我想做的是使用欧氏距离公式对对象进行排序。例如,如果我们想在Mongo中将数组A与id:0进行比较,我想应用Euclidean distance formula

distance = Math.sqrt((a1-b1)^2 + (a2-b2)^2 + ... + (an-bn)^2)

在我们的情况下:

x = Math.sqrt((1-4)^2 + (2-5)^2 + (3-6)^2 + (4-7)^2 + (5-8)^2)

我想为数据库中的每个数组找到x,然后按最小x值排序。换句话说,我想找到与我们的输入最相似的数组。

我之前在MongoDB中有一些书面的基本查询,但是我真的不确定如何解决此类问题。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

您可以从$zip开始,将输入数组与nums“配对”。然后,您可以运行$reduce来计算欧几里得公式:

db.collection.aggregate([
    {
        $addFields: {
            distance: {
                $let: {
                    vars: {
                        pow: {
                            $reduce: {
                                input: { $zip: { inputs: [ [1, 2, 3, 4, 5], "$nums" ] } },
                                initialValue: 0,
                                in: {
                                    $add: [ 
                                        "$$value", 
                                        { $pow: [ 
                                            { $subtract: [ { $arrayElemAt: [ "$$this", 0 ] }, { $arrayElemAt: [ "$$this", 1 ] } ] } , 2 ] } 
                                        ]
                                }
                            }
                        }
                    },
                    in: { $sqrt: "$$pow" }
                }
            }
        }
    },
    {
        $sort: { distance: 1 }
    }
])

Mongo Playground