【发布时间】:2017-07-27 04:42:46
【问题描述】:
我有一些市场提要数据,我正在尝试在 Ubuntu 16.04 上使用 mongodb 3.4.5 来生成给定日期范围的漂亮摘要。
这是一个示例文档。每个文档可能包含多个批量数据,分别是 Buys、Sells 和 Fills。
{
"MarketName" : "BIX",
"Nounce" : 12040,
"Buys" : [
{
"Type" : 2,
"Rate" : 0.08068147,
"Quantity" : 55.57280163
},
{
"Type" : 1,
"Rate" : 0.07980372,
"Quantity" : 0
},
{
"Type" : 0,
"Rate" : 0.07962334,
"Quantity" : 34.96018931
},
{
"Type" : 1,
"Rate" : 0.07960592,
"Quantity" : 0
}
],
"Sells" : [
{
"Type" : 0,
"Rate" : 0.08070098,
"Quantity" : 4.08189692
},
{
"Type" : 0,
"Rate" : 0.08112318,
"Quantity" : 10
},
{
"Type" : 1,
"Rate" : 0.08112319,
"Quantity" : 0
},
{
"Type" : 1,
"Rate" : 0.08149567,
"Quantity" : 0
}
],
"Fills" : [
{
"OrderType" : "SELL",
"Rate" : 0.08068147,
"Quantity" : 0.51627134,
"TimeStamp" : "2017-07-25T15:20:34.357"
},
{
"OrderType" : "BUY",
"Rate" : 0.08048147,
"Quantity" : 0.51007134,
"TimeStamp" : "2017-07-25T15:20:34.357"
}
],
"TimeStamp" : ISODate("2017-07-26T22:32:20.741+08:00")
}
我一直在尝试各种放松和小组、项目和推送等。但我没有接近我想要的输出。因为类型是对象键名,所以我正在努力寻找分组。
我正在寻找的输出是这样的。
{
"MarketName" : "RRG",
"Buys" : {
totalCount: 99, //size/count of all items in Buys array
avgRate: 0.07980372, //avg rate of all buy object items
totalQuantity: 3.09239812, //sum of all buy array items, quantity values
totalValue: 306.14741388, //avgRate * totalQuantity
type0: {
totalCount: 19, //count of items in Buy array oftype 0
avgRate: 0.07980372, //avg rate of all buy object items of type 0
totalQuantity: 3.09239812, //sum of all buy object quantity values oftype 0
totalValue: 30.14741388, //avgRate * totalQuantity
},
type1: {
totalCount: 9,
avgRate: 0.07980372,
totalQuantity: 3.09239812,
totalValue: 30.14741388,
},
type2: {
totalCount: 12,
avgRate: 0.07980372,
totalQuantity: 3.09239812,
totalValue: 30.14741388,
}
},
"Sells" : {
..same as buys format
},
"Fills" : {
..same as buys format
}
}
如果有人能以任何方式提供帮助,我将不胜感激。
这是我设法开始工作的查询,但这与我想要的还有很长的路要走,而且我不是 mongo 专家,所以很难知道如何继续。
db.getCollection('tinfo').aggregate(
[
{
$match: {
'$and': [
{'Type': {$eq: 'market'}},
{'TimeStamp': {$lte: new Date()}},
{'TimeStamp': {$gte: new Date(Date.now() - 24 * 60 * 60 * 1000)}},
{'MarketName': {$eq: 'BIX'}}
]
}
},
},
{ $unwind: "$Buys" },
{ $unwind: "$Sells" },
{ $unwind: "$Fills" },
{
$group: {
_id: {_id: "$_id", type: "$Buys.Type"},
count: {$sum: 1},
avgRate: {$avg: "$Buys.Rate"},
quantity: {$sum: "$Buys.Quantity"}
}
},{
$project: {
type: "$_id.type",
count: 1,
avgRate: 1,
quantity: 1,
total: {$multiply: ["$quantity", "$avgRate"]}
}
},{
$group: {
"_id": {
"_id" : "$_id._id"
},
"results" : {
$push: {
"k": "$type",
"v": {
"count": "$count",
"avgRate": "$avgRate",
"quantity": "$quantity"
}
}
}
}
}
])
【问题讨论】:
-
你试过什么?在输出中使用命名键从来都不是一个好主意,除非您至少使用 MongoDB 3.4,否则它完全不受支持。无论如何,这些实际上是如何存储的?文档格式似乎表明它已经“有点预聚合”,至少在所有项目似乎已经出现在相关
"MarketName"下的意义上。那么这实际上是“跨文档”吗?还是它已经在它自己的文档中,而您只是想稍微改变一下格式?请解释一下。 -
事实上,您自己的“评论”注释似乎表明这实际上只是“文档重塑”。因此,聚合框架并不是最适合这种目的。您最好在客户端代码中简单地“重新塑造”数据,因为聚合管道的语法“纯粹为此目的”而实际上“不聚合”任何东西,要简洁 比等效的客户端代码。似乎属于“仅仅因为你可以并不意味着你应该!”作为一般建议的类别。
-
我发布的源文档是我通过 websocket 提要收到的。我只是接收并保存到 mongo 而不以任何方式修改它。我想做的是根据我的匹配语句总结接收到的数据,即基于过去 30 分钟内时间戳的数据,以在类似于我给出的输出中生成此数据的摘要。
-
只是为了解释源文档只是一个从 websocket 提要接收到的 json。他们每分钟发送 50+ 个相同的文档,其中包含不同数量的嵌套购买、销售和填充条目。所以我真的不想重塑......我想将所有这些接收到的文档及其嵌套数据合并到一个输出中,该输出显示指定时间范围内包含的数据的聚合。
-
我问了你更多的问题。请回答他们。并请通过将具体细节放在“问题本身”来回答它们。人们不必为了理解您的问题而浏览 cmets。您还需要澄清您对“时间戳”的评论。哪个?有些是字符串,其中一个似乎是
Date,但您已经清楚地修改了您帖子中的实际内容,因为它不是 ISO 格式。但主要解释一下“时间戳”与此有什么关系。
标签: javascript mongodb mongodb-query aggregation-framework