如何在MongoDB查询中减去值数组?

时间:2016-07-17 01:48:32

标签: arrays mongodb subtraction

我有一组文档,其中一个字段是64个数字的数组。我想构造一个返回这些文档的查询,这个数组已被减去并求和,但是,我无法弄清楚如何做这个任务的减法部分。

示例文档可能如下所示。

{
"_id" : ObjectId("577be558033ad33f66684974"),
"syntactic_fingerprint" : [ 
    0.921382546424866, 
    0.048630952835083, 
    -0.251873761415482, 
    -0.0470362603664398, 
    0.0, 
    0.0296048410236835, 
    0.0319229736924171, 
    -0.0332595892250538, 
    -0.0694081708788872, 
    -0.117949850857258, 
    -0.0555221512913704, 
    -0.176394507288933, 
    0.0160530339926481, 
    -0.0234932824969292, 
    -0.0148191852495074, 
    0.0816841721534729, 
    0.0323052480816841, 
    0.0, 
    0.0, 
    0.0142431678250432, 
    0.0, 
    0.0, 
    0.0189650449901819, 
    0.0386682450771332, 
    0.0308650359511375, 
    0.0, 
    0.0310780759900808, 
    0.0361337624490261, 
    0.0, 
    0.0, 
    0.0, 
    0.0128832636401057, 
    -0.0125190699473023, 
    0.0, 
    -0.0282401368021965, 
    -0.0348126254975796, 
    -0.0154333971440792, 
    -0.0173368379473686, 
    -0.0443549081683159, 
    -0.0181444175541401, 
    -0.0224117543548346, 
    0.0, 
    -0.0689809918403625, 
    0.0, 
    -0.0300765186548233, 
    0.0, 
    0.0, 
    -0.0184972882270813, 
    0.0, 
    0.0, 
    0.0, 
    -0.0128712980076671, 
    0.0, 
    0.0, 
    0.0183296073228121, 
    -0.017868610098958, 
    0.0, 
    0.0, 
    -0.0145018044859171, 
    0.0134829748421907, 
    -0.0138665018603206, 
    0.0, 
    0.0, 
    0.0
]
}

我正在尝试构建一个查询,它将采用64个元素“syntactic_fingerprint”向量之一(作为常量),并从每个其他文档的指纹中减去它,然后将减去的指纹的值加总为单个号。

这似乎应该以某种方式使用聚合管道......但我似乎无法找到一种优雅的方法来实现它。

2 个答案:

答案 0 :(得分:1)

您确实需要使用聚合管道来执行此操作。它应该相对简单,您只需要$unwind数组,它将为数组中的每个元素创建一个文档,用于管道中的下一个阶段。然后,您可以将其分组为单个结果,并在文档中累积值的总和,并从每个元素中减去常量。

示例(mongoshell js):

db.myCollection.aggregate([
{
  $match: {syntactic_fingerprint: myConstant}
},
{
  $unwind: '$syntactic_fingerprint'
},
{
  $group: {
    _id: null,
    sum: {$sum: {$subtract: ['$syntactic_fingerprint', myConstant]}}
  }
}
]);

使用_id null进行分组意味着它会累积到单个对象中。

文档:

答案 1 :(得分:0)

如果在两个选择文档之间计算算术运算,则可能有一种方法可以聚合您需要的内容。但是,鉴于您提到使用数组[1,4,1,1] 查询,我认为没有一些javascript /应用程序级别查询它是不可能的。我有一种粗暴的方式,但它会返回一个数组而不是文档。

//input would be from query, output would be the result, of course.
var input = [1,4,1,1];
var output = [];
var count = 0;


//unwind the fingerprints
db.fingerprint.aggregate([
    {$unwind : "$fingerPrint" }
]).forEach(function(doc){
    id = doc._id.valueOf();
    output.push(doc.fingerPrint - input[count]);
    count++;
})

print(output);

使用上述讨论中的示例,其结果为[1, 0, 0 1]

如果您打算使用两个文档进行算术,我可以使用查询来聚合它们。