Mongodb 具有mongo聚合的稀疏向量点积

Mongodb 具有mongo聚合的稀疏向量点积,mongodb,cosine-similarity,Mongodb,Cosine Similarity,我有一个附加稀疏向量的文档,如下所示: { "_id" : ObjectId "vec" : [ { "dim" : 1, "weight" : 8 }, { "dim" : 3, "weight" : 3 } ] } 我正在尝试使用相同格式的输入向量和集合中的所有文档获取标准化点积。我可以用这个相当麻烦的聚合查询来完成它,但我想知道是否有更有效的方法 [ {$unwind: "$v

我有一个附加稀疏向量的文档,如下所示:

{
 "_id" : ObjectId
 "vec" : [ 
    {
        "dim" : 1,
        "weight" : 8
    }, 
    {
        "dim" : 3,
        "weight" : 3
    }
  ]
}
我正在尝试使用相同格式的输入向量和集合中的所有文档获取标准化点积。我可以用这个相当麻烦的聚合查询来完成它,但我想知道是否有更有效的方法

[
  {$unwind: "$vec"},
  {$project: {
    squareWeight: {multiply: ["$vec.weight","$vec.weight"]}, //for the norm
    dim: "$vec.dim",
    weight: "$vec.weight"
    inputVec: {$literal:[{dim:2,weight: 5},{dim:5, weight:2}]} //input vector
  }},
  {$project: {
    dim: 1,
    squareWeight: 1,
    scores: {
      $map: { //multiplying each input element with the vector weight
        input: "$inputVec"
        as: "input"
        in: {$cond: [
          {$eq: ["$$input.dim","$dim"]},
          {$multiply: ["$$input.weight", "$weight"]},
          0
        ]}  //in
      }  //map
    }  //scores
  }},  //project
  {$unwind: "$scores"},
  {$project: {
    scores :1,
    squareWeight: {
      $cond: [{$eq: ["scores,0"]},0,"$squareWeight"]] //to avoid multiple counting
    }
  }},
  {$group: {
    _id: "$_id",
    score: {$sum: "$scores"},
    squareSum: {$sum: "$squareWeight"}
  }}
]
我现在可以通过取
分数/(sqrt(squareSum)*| | | inputVec | |)

这感觉不是最有效的方法,所以我正在寻求改进


谢谢。

我想这就是办法。我同意这并不漂亮,但您的用例位于聚合框架区域的边缘,必须添加几个外部操作符才能使管道“漂亮”。您的意思是通过向集合中插入助手文档来添加外部操作符?从性能的角度来看,这会更有效吗?手术不需要看起来“漂亮”,但我想知道最有效的方法是什么。可能使用Map Reduce而不是聚合,或者在相同的DB格式上使用其他方式。谢谢。不,我是说MongoDB工程需要添加更多的操作符,比如
$sum
,等等。