MongoDB方面结果格式化
我有一个带有$facet的查询构造,它以以下格式返回结果: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 },
{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}