MongoDB方面结果格式化

MongoDB方面结果格式化,mongodb,mongoose,aggregation-framework,Mongodb,Mongoose,Aggregation Framework,我有一个带有$facet的查询构造,它以以下格式返回结果: {price_now: [ { _id: 'apple', price_now: 1.02 }, { _id: 'melon', price_now: 3.18 }, { _id: 'cherry', price_now: 2.57 }], price_15m: [ { _id: 'apple', price_15m: 1.08 }, { _id: 'melon', price_15m: 3.12 },

我有一个带有$facet的查询构造,它以以下格式返回结果:

{price_now: [
   { _id: 'apple', price_now: 1.02 },
   { _id: 'melon', price_now: 3.18 },
   { _id: 'cherry', price_now: 2.57 }],
price_15m: [
   { _id: 'apple', price_15m: 1.08 },
   { _id: 'melon', price_15m: 3.12 },
   { _id: 'cherry', price_15m: 2.82 }],
price_30m: [
   { _id: 'apple', price_30m: 1.05 },
   { _id: 'melon', price_30m: 3.04 },
   { _id: 'cherry', price_30m: 2.94 }]
如何以这种格式获得结果?:

{ _id: 'apple', price_now: 1.02, price_15m: 1.08, price_30m: 1.05 },
{ _id: 'melon', price_now: 3.18, price_15m: 3.12, price_30m: 3.04 },
{ _id: 'cherry', price_now: 2.57, price_15m: 2.82, price_30m: 2.94 }
完整查询如下所示:

var today = new Date();
var shift_15m = new Date(today.getTime()-15*60*1000);
var shift_30m = new Date(today.getTime()-30*60*1000);

food.aggregate( [
    {
        $facet: {
            price_now: [
                {
                    $group: {
                        _id: "$name",
                        price_now: {$last: "$price"}
                    }
                }
            ],
            price_15m: [
                {
                    $match: {
                        date: { "$lte": shift_15m }
                    }
                }, {
                    $group: {
                        _id: "$name",
                        price_5m: {$last: "$price"}
                    }
                }
            ],
            price_30m: [
                {
                    $match: {
                        date: { "$lte": shift_30m }
                    }
                }, {
                    $group: {
                        _id: "$name",
                        price_30m: {$last: "$price"}
                    }
                }
            ]
        }
    }
])
我需要在一个查询中获得不同时间间隔的每个产品的价格。也许你知道一个更好更快的方法来获取不同时间的价格。
我的MongoDB版本是v3.6.0。我在Node.js应用程序中使用mongoose。

根据您的使用案例,它可能效率不高,但可以通过facets操作以以下方式合并阵列

确保所有facets类别都按名称排序,并且所有数组中的每一行都包含相同的产品

然后,您可以先
$zip
所有方面类别,然后
$reduce
每个类别组合所有不同的价格,并重复所有产品

您可以在facet阶段之后添加以下阶段

{"$project":{
  "data":{
    "$map":{
      "input":{"$zip":{"inputs":["$price_10s","$price_30s", "$price_30m"],"useLongestLength":true}},
      "as":"item",
      "in":{
        "$reduce":{
          "input":"$$item",
          "initialValue":{},
          "in":{"$mergeObjects":["$$this","$$value"]}
        }
      }
    }
  }
}}

@Veeram,这是完整的结构

food.aggregate( [
    {
        $facet: {
            price_now: [
                {
                    $group: {
                        _id: "$market_name",
                        price_now: {$last: "$my_time_stamp"}
                    }
                }
            ],
            price_5m: [
                {
                    $match: {
                        my_time_stamp: { "$lte": shift_5m }
                    }
                }, {
                    $group: {
                        _id: "$market_name",
                        price_5m: {$last: "$my_time_stamp"}
                    }
                }
            ],
            price_15m: [
                {
                    $match: {
                        my_time_stamp: { "$lte": shift_15m }
                    }
                }, {
                    $group: {
                        _id: "$market_name",
                        price_15m: {$last: "$my_time_stamp"}
                    }
                }
            ]
        }
    }, {
        "$project":{
            "data":{
                "$map":{
                    "input":{"$zip":{"inputs":["$price_now","$price_5m", "price_15m"],"useLongestLength":true}},
                    "as":"item",
                    "in":{
                        "$reduce":{
                            "input":"$$item",
                            "initialValue":{},
                            "in":{"$mergeObjects":["$$this","$$value"]}
                        }
                    }
                }
            }
        }
    }
], function (err, result) {
    if (err) {
         console.log(err);
    } else {
        console.log(result)
    };
});

$facet
之前添加一个
$match
阶段,将产品限制在今天和您的最高范围之间。您是否总是在每个时间类别中有固定数量的退货产品?只是试着理解,以便我们可以格式化它们。@Veeram我只存储过去6小时的价格。新产品可以多次添加到DB中。好的,我已经添加了一个答案。看看它是否对您有帮助。我发现了以下错误:“$zip在输入中找到了一个非数组表达式:“price_30m””代码:34468,代码名:“Location34468”哦,很抱歉它应该是zip中的
$price_30m
。在下一篇评论中修复完整的构建。请检查一下@VeeramTry
{“$zip”:{“输入”:[“$price_now”、“$price_5m”、“$price_15m”]、“useLongestLength”:true}