如何从 MongoDB 集合中获取聚合
How to Get an Aggregate from a MongoDB Collection
以下集合包含不同交易品种的报价(在本例中为 BTCUSD
和 BTCEUR
):
{ "_id" : ObjectId("5a08d2b956df9b2302759d1a"), "symbol" : "BTCUSD", "time" : ISODate("2013-04-13T00:00:00Z"), "open" : 112, "close" : 91.1, "high" : 130, "low" : 81.12, "volume" : 23866.6770456 }
{ "_id" : ObjectId("5a08d2b956df9b2302759d1c"), "symbol" : "BTCUSD", "time" : ISODate("2013-04-14T00:00:00Z"), "open" : 91.1, "close" : 90.171, "high" : 109, "low" : 20, "volume" : 16437.2196645 }
{ "_id" : ObjectId("5a08d2b956df9b2302759d1e"), "symbol" : "BTCEUR", "time" : ISODate("2013-04-15T00:00:00Z"), "open" : 89.86, "close" : 83.302, "high" : 104, "low" : 71.497, "volume" : 16393.12856398 }
{ "_id" : ObjectId("5a08d2b956df9b2302759d20"), "symbol" : "BTCEUR", "time" : ISODate("2013-04-16T00:00:00Z"), "open" : 84.27, "close" : 67.588, "high" : 84.48, "low" : 0.01, "volume" : 26092.5432296 }
如何获取 Go
集合中实际存在的符号列表?例如,我正在寻找的结果是:
{ "BTCUSD", "BTCEUR" }
这样我就可以从交易服务中检索最新的报价单值,而不必将我感兴趣的符号存储在某个地方。
来自 mongo
shell 我试过了...
db.candles.aggregate({$group: {_id:"$symbol"}})
...结果如下:
{ "_id" : "BTCUSD" }
{ "_id" : "BTCEUR" }
Go
使用 mgo
的等价物是什么?是否可以只获取符号数组而不是 "_id" : "value"
对的集合?
使用Distinct()
使用 collection.distinct()
最容易完成您想要的。在 MongoDB 控制台中它看起来像这样:
db.candles.distinct("symbol")
而在 Go 中,使用 mgo
、Query.Distinct()
:
var sess *mgo.Session = ... // Acquire session
c := sess.DB("dbname").C("candles")
var symbols []string
err := c.Find(nil).Distinct("symbol", &symbols)
if err != nil {
log.Printf("Error: %v", err)
return
}
fmt.Println(symbols)
使用聚合框架
您也可以使用 MongoDB 聚合来完成此操作,该聚合可通过 Collection.Pipe()
方法获得。你得传一个切片给它,每个元素对应一个聚合阶段。
聚合的结果始终是文档列表,因此如果您希望结果是字符串片段,则必须手动执行 "conversion"。
var sess *mgo.Session = ... // Acquire session
c := sess.DB("dbname").C("candles")
pipe := c.Pipe([]bson.M{
{
"$group": bson.M{
"_id": "$symbol",
},
},
})
var results = []bson.M{}
if err := pipe.All(&results); err != nil {
log.Printf("Error: %v", err)
return
}
// results holds {"_id": "symbol"} documents
// To get a slice of symbols:
symbols := make([]string, len(results))
for i, doc := range results {
symbols[i] = doc["_id"].(string)
}
fmt.Println(symbols)
有关如何获取值片段而不是文档的更多技术,请参阅
以下集合包含不同交易品种的报价(在本例中为 BTCUSD
和 BTCEUR
):
{ "_id" : ObjectId("5a08d2b956df9b2302759d1a"), "symbol" : "BTCUSD", "time" : ISODate("2013-04-13T00:00:00Z"), "open" : 112, "close" : 91.1, "high" : 130, "low" : 81.12, "volume" : 23866.6770456 }
{ "_id" : ObjectId("5a08d2b956df9b2302759d1c"), "symbol" : "BTCUSD", "time" : ISODate("2013-04-14T00:00:00Z"), "open" : 91.1, "close" : 90.171, "high" : 109, "low" : 20, "volume" : 16437.2196645 }
{ "_id" : ObjectId("5a08d2b956df9b2302759d1e"), "symbol" : "BTCEUR", "time" : ISODate("2013-04-15T00:00:00Z"), "open" : 89.86, "close" : 83.302, "high" : 104, "low" : 71.497, "volume" : 16393.12856398 }
{ "_id" : ObjectId("5a08d2b956df9b2302759d20"), "symbol" : "BTCEUR", "time" : ISODate("2013-04-16T00:00:00Z"), "open" : 84.27, "close" : 67.588, "high" : 84.48, "low" : 0.01, "volume" : 26092.5432296 }
如何获取 Go
集合中实际存在的符号列表?例如,我正在寻找的结果是:
{ "BTCUSD", "BTCEUR" }
这样我就可以从交易服务中检索最新的报价单值,而不必将我感兴趣的符号存储在某个地方。
来自 mongo
shell 我试过了...
db.candles.aggregate({$group: {_id:"$symbol"}})
...结果如下:
{ "_id" : "BTCUSD" }
{ "_id" : "BTCEUR" }
Go
使用 mgo
的等价物是什么?是否可以只获取符号数组而不是 "_id" : "value"
对的集合?
使用Distinct()
使用 collection.distinct()
最容易完成您想要的。在 MongoDB 控制台中它看起来像这样:
db.candles.distinct("symbol")
而在 Go 中,使用 mgo
、Query.Distinct()
:
var sess *mgo.Session = ... // Acquire session
c := sess.DB("dbname").C("candles")
var symbols []string
err := c.Find(nil).Distinct("symbol", &symbols)
if err != nil {
log.Printf("Error: %v", err)
return
}
fmt.Println(symbols)
使用聚合框架
您也可以使用 MongoDB 聚合来完成此操作,该聚合可通过 Collection.Pipe()
方法获得。你得传一个切片给它,每个元素对应一个聚合阶段。
聚合的结果始终是文档列表,因此如果您希望结果是字符串片段,则必须手动执行 "conversion"。
var sess *mgo.Session = ... // Acquire session
c := sess.DB("dbname").C("candles")
pipe := c.Pipe([]bson.M{
{
"$group": bson.M{
"_id": "$symbol",
},
},
})
var results = []bson.M{}
if err := pipe.All(&results); err != nil {
log.Printf("Error: %v", err)
return
}
// results holds {"_id": "symbol"} documents
// To get a slice of symbols:
symbols := make([]string, len(results))
for i, doc := range results {
symbols[i] = doc["_id"].(string)
}
fmt.Println(symbols)
有关如何获取值片段而不是文档的更多技术,请参阅