mongodb 烛条查询
mongodb candlestick query
我需要从 mongo 中查询财务数据并生成每日 Candle Stick 图。
集合架构类似于:
{
symbol: 'GOOG',
amount: 1000,
rate: 123,
created_at: ISODate('some point in time')
}
图表中的每个条目(即每一天)应包含 4 个值:
- 高(最大(速率))
- 低(最小(速率))
- 开放(给定日期的第一汇率)
- 收盘价(给定日期的最后汇率)
知道如何构建查询吗?
好的,在 @David Peleg sent me this repo 之后想通了:
db.collection.aggregate([
{$match:{
symbol:'GOOG'
}},
{$project:{
"day":{
"y": {"$year":"$created_at"},
"m": {"$month":"$created_at"},
"d": {"$dayOfMonth": "$created_at"}
},
created_at: 1,
rate: 1
}},
{"$sort":{"created_at":1}},
{"$group":{
"_id": "$day",
"created_at": {"$first":"$created_at"},
"open": {"$first":"$rate"},
"close": {"$last":"$rate"},
"high": {"$max":"$rate"},
"low": {"$min":"$rate"},
}},
{$project:{
"_id": "$_id",
"rates":{
"open": "$open",
"close": "$close",
"high": "$high",
"low": "$low"
}
}},
{"$sort":{"_id":1}}
])
我一直在对我正在开发的项目进行类似的查询,很高兴看到我得出了类似的结论。
我的传入数据来自 Robinhood 的 API;它看起来与你的相似,但给了我字符串中的日期戳,所以我添加了一个 $toDate 和 $toString 来将字符串翻转为 Date 对象。我可能会选择将传入的日期戳转换为 Ruby 中的时间对象,然后删除此处的额外工作。
我仍在完善我的分组,因为我不确定我是否真的需要两个。我的传入流有时会重复数据(每秒,由于字符串日期戳的情况),所以第一组是清理它,以免错误地膨胀第二组中的 { "$sum": "$volume" }。
我的 $project returns 我请求的前一分钟 59 秒范围内的 1m 烛台数据。这些密钥与 Robinhood 的 API 历史相匹配,因此我可以将它们视为代码中的同一对象。
var date_now = new Date(new ISODate("2019-10-21T20:00:00.000Z"))
var date_end = new Date(date_now.getTime() - 1000 * 1)
var date_begin = new Date(date_now.getTime() - 1000 * 60 * 10)
db.quotes.aggregate([
{ "$addFields": { "date": { "$toDate": "$time_pulled" } } },
{ $match: { symbol: "NUGT",
date: { "$gte": date_begin,
"$lt": date_end } } },
{ $group: { _id: "$date", // group by date to eliminate dups
"symbol": { "$first": "$symbol" },
"price": { "$max": "$last_trade_price" },
"volume": { "$max": "$volume" } } },
{ $sort: { _id: 1 } }, // sort by date to get correct first/last prices
{ $group: { _id: "$symbol",
//"date_begin": { "$first": { "$toString": "$_id" } },
//"date_end": { "$last": { "$toString": "$_id" } },
"high_price": { "$max": "$price" },
"low_price": { "$min": "$price" },
"open_price": { "$first": "$price" },
"close_price": { "$last": "$price" },
"volume": { "$sum": "$volume" } } },
{ $project: { _id: 1,
begins_at: { "$toString": date_begin },
volume: 1,
high_price: 1,
low_price: 1,
open_price: 1,
close_price: 1 } }
])
结果:
/* 1 */
{
"_id" : "NUGT",
"high_price" : "26.860000",
"low_price" : "26.740000",
"open_price" : "26.834200",
"close_price" : "26.820000",
"volume" : 392086.0,
"begins_at" : "2019-10-21T19:50:00.000Z"
}
我需要从 mongo 中查询财务数据并生成每日 Candle Stick 图。
集合架构类似于:
{
symbol: 'GOOG',
amount: 1000,
rate: 123,
created_at: ISODate('some point in time')
}
图表中的每个条目(即每一天)应包含 4 个值:
- 高(最大(速率))
- 低(最小(速率))
- 开放(给定日期的第一汇率)
- 收盘价(给定日期的最后汇率)
知道如何构建查询吗?
好的,在 @David Peleg sent me this repo 之后想通了:
db.collection.aggregate([
{$match:{
symbol:'GOOG'
}},
{$project:{
"day":{
"y": {"$year":"$created_at"},
"m": {"$month":"$created_at"},
"d": {"$dayOfMonth": "$created_at"}
},
created_at: 1,
rate: 1
}},
{"$sort":{"created_at":1}},
{"$group":{
"_id": "$day",
"created_at": {"$first":"$created_at"},
"open": {"$first":"$rate"},
"close": {"$last":"$rate"},
"high": {"$max":"$rate"},
"low": {"$min":"$rate"},
}},
{$project:{
"_id": "$_id",
"rates":{
"open": "$open",
"close": "$close",
"high": "$high",
"low": "$low"
}
}},
{"$sort":{"_id":1}}
])
我一直在对我正在开发的项目进行类似的查询,很高兴看到我得出了类似的结论。
我的传入数据来自 Robinhood 的 API;它看起来与你的相似,但给了我字符串中的日期戳,所以我添加了一个 $toDate 和 $toString 来将字符串翻转为 Date 对象。我可能会选择将传入的日期戳转换为 Ruby 中的时间对象,然后删除此处的额外工作。
我仍在完善我的分组,因为我不确定我是否真的需要两个。我的传入流有时会重复数据(每秒,由于字符串日期戳的情况),所以第一组是清理它,以免错误地膨胀第二组中的 { "$sum": "$volume" }。
我的 $project returns 我请求的前一分钟 59 秒范围内的 1m 烛台数据。这些密钥与 Robinhood 的 API 历史相匹配,因此我可以将它们视为代码中的同一对象。
var date_now = new Date(new ISODate("2019-10-21T20:00:00.000Z"))
var date_end = new Date(date_now.getTime() - 1000 * 1)
var date_begin = new Date(date_now.getTime() - 1000 * 60 * 10)
db.quotes.aggregate([
{ "$addFields": { "date": { "$toDate": "$time_pulled" } } },
{ $match: { symbol: "NUGT",
date: { "$gte": date_begin,
"$lt": date_end } } },
{ $group: { _id: "$date", // group by date to eliminate dups
"symbol": { "$first": "$symbol" },
"price": { "$max": "$last_trade_price" },
"volume": { "$max": "$volume" } } },
{ $sort: { _id: 1 } }, // sort by date to get correct first/last prices
{ $group: { _id: "$symbol",
//"date_begin": { "$first": { "$toString": "$_id" } },
//"date_end": { "$last": { "$toString": "$_id" } },
"high_price": { "$max": "$price" },
"low_price": { "$min": "$price" },
"open_price": { "$first": "$price" },
"close_price": { "$last": "$price" },
"volume": { "$sum": "$volume" } } },
{ $project: { _id: 1,
begins_at: { "$toString": date_begin },
volume: 1,
high_price: 1,
low_price: 1,
open_price: 1,
close_price: 1 } }
])
结果:
/* 1 */
{
"_id" : "NUGT",
"high_price" : "26.860000",
"low_price" : "26.740000",
"open_price" : "26.834200",
"close_price" : "26.820000",
"volume" : 392086.0,
"begins_at" : "2019-10-21T19:50:00.000Z"
}