Mongodb 不同结构文档的求和操作

Mongodb 不同结构文档的求和操作,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我正在尝试使用聚合管道,以便能够使用mongodb作为后端来创建一个报告表(排序、分页等)。我遇到了一个问题,我的模式不同,但我需要添加所有值。我试图使用unwind命令,但它只在数组中工作,因此没有其他选择 示例文档 { "_id": "first", "apple": 6, "pears": 7, "total_fruits": "13" }, { "_id": "second", "apple": 6, "bananas": 2, "total_fruit

我正在尝试使用聚合管道,以便能够使用mongodb作为后端来创建一个报告表(排序、分页等)。我遇到了一个问题,我的模式不同,但我需要添加所有值。我试图使用unwind命令,但它只在数组中工作,因此没有其他选择

示例文档

{
  "_id": "first",
  "apple": 6,
  "pears": 7,
  "total_fruits": "13"
},

{
  "_id": "second",
  "apple": 6,
  "bananas": 2,
  "total_fruits": "8"
}
期望的结果

{
  "_id": "result",
  "apple": 12,
  "pears": 7,
  "bananas": 2,
  "total_fruits": "21"
}

为什么不使用
mapReduce()
,而不是聚合

对于您的示例文档:

{
  "_id": "first",
  "apple": 6,
  "pears": 7,
  "total_fruits": "13"
},
{
  "_id": "second",
  "apple": 6,
  "bananas": 2,
  "total_fruits": "8"
}
您可以对每个字段名调用函数:

console.log(sumKeyFromCollection("collectionName", "apple"));
> { "_id": "...", "apple": 12 }
然后使用它们中的每一个生成结果文档:

var fruits = [ "apple", "bananas", "total_fruits" ];
var results = []; 

for (var i = 0; i < fruits.length; i++) {
  results.push(sumKeyFromCollection("collectionName", fruits[i]));
}

它返回一个唯一字段名数组(即使它们只出现在一个文档中)。

您知道集合中所有字段的名称吗,或者它们是动态的?如果您可以使用类似于
{id:“first”,fruits:[{name:“apple”,count:6},{name:“pears”,count:7},“total\u fruits”:13}
,,那么你的管道将更容易write@Styvane这些字段是动态的。这就是为什么很难做到的原因。@AliDehghani我必须在处理过程中添加一个步骤来做到这一点,但这可能是一个选项。类似的方法会奏效。我寻找管道选项的原因是,在分组之后,我需要应用排序/跳过和限制。所以现在持有map reduce选项是可能的,但是探索我的选项。
var fruits = [ "apple", "bananas", "total_fruits" ];
var results = []; 

for (var i = 0; i < fruits.length; i++) {
  results.push(sumKeyFromCollection("collectionName", fruits[i]));
}
function getAllCollectionFieldNames(collectionName) {
    mr = db.runCommand({
      "mapreduce" : collectionName,
      "map" : function() {
        for (var key in this) { emit(key, null); }
      },
      "reduce" : function(key, stuff) { return null; }, 
      "out": "my_collection" + "_keys"
    });
    db[mr.result].distinct("_id");
}