Golang中MongoDB的插入操作如何实现?
Golang中MongoDB的插入操作如何实现? 大家好,
我有一个存储大量数据的数组,需要将这些数据插入到MongoDB中。
我能够使用以下代码实现这一目标,但耗时较长。是否有其他方法可以将大型数组数据推送到MongoDB中?
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
// Optional. Switch the session to a monotonic behavior.
session.SetMode(mgo.Monotonic, true)
c := session.DB("Test").C("Indicators")
for i := 0; i < len(HeadDet); i++ {
err = c.Insert(HeadDet[i])
}
if err != nil {
log.Fatal(err)
}
我已参考以下链接: https://labix.org/mgo
谢谢。
更多关于Golang中MongoDB的插入操作如何实现?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
你收到什么错误信息了?有更多详细信息吗?"它不工作"这样的描述无法帮助我们帮助你。具体是什么不工作?它是怎么不工作的?
我尝试按照建议使用 goroutine 将数据插入到 MongoDB 中。但是对于 50 到 100 条记录它可以正常工作,而对于大量记录却无法工作。有人能帮忙解决这个问题吗?
感谢。我已经处理了错误。但它没有插入到数据库中。也没有抛出任何错误。我用一些会生成50到100条记录的测试数据检查了相同的代码,这些记录都成功插入到数据库中没有问题。只有大数据量(300万条记录)才会出现这个问题。
Alex_Roz:
col.Insert(doc…)
文档显示 col.Insert() 会返回一个错误,而你忽略了它。可以这样做来了解问题所在:
err := col.Insert(doc...)
if err != nil {
fmt.Errorf("insert error: %s\n", err) //
}
关键在于:永远不要忽略错误,务必处理它们。
感谢您的建议。我能够在3分钟内存储约30万条记录。
使用以下代码:
//HeadDet 包含30万条记录
docs := make([]interface{}, len(HeadDet))
for i := range HeadDet{
docs[i] = HeadDet[i]
}
//将文档插入数据库
collection.Insert(docs...)
但我希望能在几秒钟内插入数组数据,而不是3分钟。迭代数组数据很耗时。有没有其他方法可以将时间减少到几秒钟?
谢谢。
使用工作线程(goroutine)并在每个线程中创建独立的mgo会话(多连接)。请参考mgo会话的Copy()方法。具体执行速度取决于您的Mongo服务器性能。
// 示例代码展示如何在工作线程中使用独立的mgo会话
func worker(session *mgo.Session, jobs <-chan Job) {
// 为每个工作线程创建会话副本
localSession := session.Copy()
defer localSession.Close()
for job := range jobs {
// 处理任务...
}
}
那么如何判断它没有正常工作呢?你怎么知道出现了错误?是你的程序确实结束了,然后你检查数据库发现没有插入数据吗?日志是否显示有任何尝试插入数据的记录?等等。
你提供的示例代码并不完整,而且你提供的信息量太少,我们难以提供帮助。请提供更多细节,并开始进行调试工作,可以在代码中适当位置添加一些打印语句,甚至可以使用调试器(例如 https://github.com/derekparker/delve)。
另外需要说明的是,尽管那个特定的调用可能没有抛出错误,但我还是要强调你应该始终检查并处理错误。
我不确定 mgo 是否使用与我了解的其他语言数据库驱动类似的术语,但我会查看 Bulk 方法。
此外,似乎你应该寻找另一个驱动,因为 mgo 看起来已不再维护:
mgo package - gopkg.in/mgo.v2 - Go Packages
#########################################################
此驱动已不再维护!详情请见:
mgo/README.md at v2-unstable · go-mgo/mgo · GitHub
#########################################################
我没有收到任何错误信息。程序能够成功向MongoDB插入50到100条记录。但当我尝试插入大量记录时,数据无法插入数据库。我使用的是以下代码:
package test
import (
"os"
"gopkg.in/mgo.v2"
)
var Db *mgo.Session
type DbLink struct {
DbName string
}
func NewDbSession(url string) {
var e error
Db, e = mgo.Dial(url)
if e != nil {
panic(e)
os.Exit(-1)
}
}
func PerformInsertOperation() {
NewDbSession("localhost")
session := Db.Copy()
//defer session.Close()
col := session.DB("TEST").C("HeadDet")
ch := make(chan bool)
go func(doc []interface{}) {
col.Insert(doc...)
ch <- true
}(HeadDet)
}
谢谢。
我在一个项目中切换到了这个分支
Go语言的MongoDB驱动。通过在GitHub上创建账户来为globalsign/mgo开发做贡献。
因为官方驱动仍处于alpha阶段。
globalsign/mgo/blob/1ca0a4f7cbcbe61c005d1bd43fdd8bb8b71df6bc/bulk.go#L171
action = &b.actions[len(b.actions)-1]
}
for i := 0; i < opcount; i++ {
action.idxs = append(action.idxs, b.opcount)
b.opcount++
}
return action
}
// Insert queues up the provided documents for insertion.
func (b *Bulk) Insert(docs ...interface{}) {
action := b.action(bulkInsert, len(docs))
action.docs = append(action.docs, docs...)
}
// Remove queues up the provided selectors for removing matching documents.
// Each selector will remove only a single matching document.
func (b *Bulk) Remove(selectors ...interface{}) {
action := b.action(bulkRemove, len(selectors))
for _, selector := range selectors {
if selector == nil {
遗憾的是,这个驱动不支持用于取消操作的上下文方法,而官方驱动支持。
在Golang中使用mgo库插入大量数据时,使用Insert方法进行单条插入确实会导致性能问题。对于批量插入,可以使用Insert方法的变体来一次性插入整个数组,或者使用Bulk操作来提高性能。
以下是两种优化方法:
方法1:使用Insert批量插入
package main
import (
"log"
"gopkg.in/mgo.v2"
)
type Indicator struct {
// 根据你的数据结构定义字段
ID int `bson:"_id"`
Name string `bson:"name"`
}
func main() {
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
c := session.DB("Test").C("Indicators")
// 假设HeadDet是你的数据数组
var HeadDet []Indicator
// 使用Insert一次性插入整个切片
err = c.Insert(HeadDet...)
if err != nil {
log.Fatal(err)
}
}
方法2:使用Bulk操作(推荐用于大量数据)
package main
import (
"log"
"gopkg.in/mgo.v2"
)
func main() {
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
c := session.DB("Test").C("Indicators")
// 创建Bulk操作
bulk := c.Bulk()
// 假设HeadDet是你的数据数组
var HeadDet []interface{} // 使用interface{}类型
// 将所有文档添加到Bulk操作中
for _, doc := range HeadDet {
bulk.Insert(doc)
}
// 执行批量插入
_, err = bulk.Run()
if err != nil {
log.Fatal(err)
}
}
方法3:使用Unordered Bulk操作(性能最佳)
package main
import (
"log"
"gopkg.in/mgo.v2"
)
func main() {
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
c := session.DB("Test").C("Indicators")
// 创建无序Bulk操作(允许部分失败继续执行)
bulk := c.Bulk()
bulk.Unordered()
var HeadDet []interface{}
// 批量添加所有文档
for _, doc := range HeadDet {
bulk.Insert(doc)
}
// 执行批量操作
_, err = bulk.Run()
if err != nil {
log.Fatal(err)
}
}
使用Bulk操作可以显著提高插入大量数据的性能,因为它减少了网络往返次数和数据库操作的开销。对于数万条以上的数据,性能提升会非常明显。


